From 54cb02a4f1f0a4c1fd99c8c78ba6e8391c78730f Mon Sep 17 00:00:00 2001
From: iadgovuser58 <124906646+iadgovuser58@users.noreply.github.com>
Date: Mon, 22 Apr 2024 19:09:01 -0400
Subject: [PATCH] spdm processing - added Device Security Event Data Pci
 Context

---
 .../events/DeviceSecurityEventData.java       |   9 +-
 .../events/DeviceSecurityEventDataBase.java   | 111 +++---------------
 .../DeviceSecurityEventDataDeviceContext.java |  48 ++++----
 .../events/DeviceSecurityEventDataHeader.java |  13 +-
 .../DeviceSecurityEventDataHeaderBase.java    |  13 +-
 .../DeviceSecurityEventDataPciContext.java    | 111 ++++++++++++++++++
 .../events/EvEfiSpdmFirmwareBlob.java         |   3 -
 7 files changed, 176 insertions(+), 132 deletions(-)
 create mode 100644 HIRS_Utils/src/main/java/hirs/utils/tpm/eventlog/events/DeviceSecurityEventDataPciContext.java

diff --git a/HIRS_Utils/src/main/java/hirs/utils/tpm/eventlog/events/DeviceSecurityEventData.java b/HIRS_Utils/src/main/java/hirs/utils/tpm/eventlog/events/DeviceSecurityEventData.java
index f7c4d8b6..68f55960 100644
--- a/HIRS_Utils/src/main/java/hirs/utils/tpm/eventlog/events/DeviceSecurityEventData.java
+++ b/HIRS_Utils/src/main/java/hirs/utils/tpm/eventlog/events/DeviceSecurityEventData.java
@@ -19,14 +19,19 @@ public class DeviceSecurityEventData extends DeviceSecurityEventDataBase {
      * @param dSEDbytes byte array holding the DeviceSecurityEventData.
      */
     public DeviceSecurityEventData(final byte[] dSEDbytes) throws UnsupportedEncodingException {
-        super(dSEDbytes);
         dsedHeader = new DeviceSecurityEventDataHeader(dSEDbytes);
+        extractDeviceContext(dSEDbytes, dsedHeader.getDSEDheaderByteSize());
     }
 
+    /**
+     * Returns a human readable description of the data within this structure.
+     *
+     * @return a description of this structure.
+     */
     public String toString() {
         String dsedInfo = "";
         dsedInfo += dsedHeader.toString();
-//      dsedInfo += dsedDeviceContext.toString();
+        dsedInfo += getDsedDeviceContext().toString();
         return dsedInfo;
     }
 }
diff --git a/HIRS_Utils/src/main/java/hirs/utils/tpm/eventlog/events/DeviceSecurityEventDataBase.java b/HIRS_Utils/src/main/java/hirs/utils/tpm/eventlog/events/DeviceSecurityEventDataBase.java
index 46f3bdba..1481d6aa 100644
--- a/HIRS_Utils/src/main/java/hirs/utils/tpm/eventlog/events/DeviceSecurityEventDataBase.java
+++ b/HIRS_Utils/src/main/java/hirs/utils/tpm/eventlog/events/DeviceSecurityEventDataBase.java
@@ -8,7 +8,8 @@ import java.nio.charset.StandardCharsets;
 
 
 /**
- * Abstract base class to process the DEVICE_SECURITY_EVENT_DATA or ..DATA2 event per PFP.
+ * Abstract base class to process the DEVICE_SECURITY_EVENT_DATA or ..DATA2 event.
+ * Parses event data for DEVICE_SECURITY_EVENT_DATA per PFP v1.06 Rev52 Table 20.
  * The event data comes in 2 forms:
  *    1) DEVICE_SECURITY_EVENT_DATA or
  *    2) DEVICE_SECURITY_EVENT_DATA2
@@ -39,118 +40,44 @@ import java.nio.charset.StandardCharsets;
  *      ...                             ...
  * }
  * <p>
- * Notes: Parses event data for an DEVICE_SECURITY_EVENT_DATA per PFP v1.06 Rev52 Table 20.
+ * Notes:
  * 1. Has an EventType of EV_EFI_SPDM_FIRMWARE_BLOB (0x800000E1)
- * 2. Digest of 48 bytes
- * 3. Event content defined as DEVICE_SECURITY_EVENT_DATA Struct.
- * 4. First 16 bytes of the structure header is an ASCII "SPDM Device Sec"
+ * 2. Event content defined as DEVICE_SECURITY_EVENT_DATA Struct.
+ * 3. First 16 bytes of the structure header is an ASCII "SPDM Device Sec"
  * <p>
  * Only a few of the Device Security Event Data events have been implemented as there are many,
  * but only those that were reported using the test devices at hand.
  * Without test patterns, the processing may lead to an un-handled exception.
+ * For now, the only test pattern uses ..DeviceContext with PCI only, without USB -> assume only 1
+ * even though the spec says both are in the data structure. If it is only 1, though, there's no
+ * method to tell them apart.
  */
 public abstract class DeviceSecurityEventDataBase {
 
-//    /**
-//     * Signature (text) data.
-//     */
-//    @Getter
-//    private String signature = "";
-//    /**
-//     * Version determines data structure used (..DATA or ..DATA2).
-//     */
-//    @Getter
-//    private String version = "";
-//    /**
-//     * Contains the human-readable info inside the Device Security Event.
-//     */
-//    @Getter
-//    private String dsedInfo = "";
-//    /**
-//     * DeviceSecurityEventDataHeader Object.
-//     */
-//    @Getter
-//    private DeviceSecurityEventDataHeader dsedHeader = null;
     /**
      * DeviceSecurityEventDataDeviceContext Object.
      */
     @Getter
     private DeviceSecurityEventDataDeviceContext dsedDeviceContext = null;
 
+    /**
+     * DeviceSecurityEventData Default Constructor.
+     *
+     */
     public DeviceSecurityEventDataBase() {
 
     }
 
-    /**
-     * DeviceSecurityEventData Constructor.
-     *
-     * @param dSEDbytes byte array holding the DeviceSecurityEventData.
-     */
-    public DeviceSecurityEventDataBase(final byte[] dSEDbytes) {
+    public void extractDeviceContext(final byte[] dSEDbytes, int startByte) {
 
-//        byte[] signatureBytes = new byte[UefiConstants.SIZE_16];
-//        System.arraycopy(dSEDbytes, 0, signatureBytes, 0, UefiConstants.SIZE_16);
-//        //signature = HexUtils.byteArrayToHexString(signatureBytes);
-//        signature = new String(signatureBytes, StandardCharsets.UTF_8)
-//                .substring(0, UefiConstants.SIZE_15);       // size 15 bc last letter is a 00 (null)
-//
-//        byte[] versionBytes = new byte[UefiConstants.SIZE_2];
-//        System.arraycopy(dSEDbytes, UefiConstants.OFFSET_16, versionBytes, 0,
-//                UefiConstants.SIZE_2);
-//        version = HexUtils.byteArrayToHexString(versionBytes);
+        int deviceContextLength = dSEDbytes.length - startByte;
 
-//        int byteOffset = 0;
-//        byteOffset = dsedHeader.getDsedHeaderByteSize();
+        // get the device type ID
+        byte[] deviceContextBytes = new byte[deviceContextLength];
+        System.arraycopy(dSEDbytes, startByte, deviceContextBytes, 0,
+                deviceContextLength);
+        dsedDeviceContext = new DeviceSecurityEventDataDeviceContext(deviceContextBytes);
 
-        // If version is 0x01, the event is a DEVICE_SECURITY_EVENT_DATA
-        // If version is 0x02, the event is a DEVICE_SECURITY_EVENT_DATA2
-//        switch (version) {
-//            case "0100":
-//                dsedHeader = new DeviceSecurityEventDataHeader(dSEDbytes);
-////                dsedDeviceContext = new DeviceSecurityEventDataDeviceContext(dSEDbytes,
-////                        dsedHeader.getDSEDheaderByteSize());
-//                break;
-//            case "0200":
-//                dsedHeader = new DeviceSecurityEventDataHeader(dSEDbytes);
-////            dsedSubHeader = new DeviceSecurityEventDataSubHeader(dSEDbytes,byteOffset);
-////            byteOffset = dsedHeader.getDSEDsubHeaderByteSize();
-////                dsedDeviceContext = new DeviceSecurityEventDataDeviceContext(dSEDbytes, byteOffset);
-//                break;
-//            default:
-//                break;
-
-
-//        if (version == "1") {
-//            dSEDinfo =+
-//                    dSEDataHeader.getDSEDheaderInfo();
-//            dSEDinfo =+
-//                    dsedDeviceContext.getdSEDdeviceContextInfo();
-//        } else if (version == "2") {
-//            dSEDinfo =+
-//                    dSEDheader.getDSEDheaderInfo();
-//            dSEDinfo =+
-//                    dsedSubHeader.getDSEDsubHeaderInfo();
-//            dSEDinfo =+
-//                    dsedDeviceContext.getDSEDdeviceContextInfo();
-//        }
-//        }
     }
 
-    public String toString() {
-        String dsedInfo = "";
-//        switch (version) {
-//            case "0100":
-//                dsedInfo += dsedHeader.toString();
-////                dsedInfo += dsedDeviceContext.toString();
-//                break;
-//            case "0200":
-////                dsedInfo += dsedHeader.toString();
-////                dsedInfo += dsedSubHeader.toString();
-////                dsedInfo += dsedDeviceContext.toString();
-//                break;
-//            default:
-//                dsedInfo += " Unknown SPDM Device Security Event Data version " + version + " found" + "\n";
-//        }
-        return dsedInfo;
-    }
 }
diff --git a/HIRS_Utils/src/main/java/hirs/utils/tpm/eventlog/events/DeviceSecurityEventDataDeviceContext.java b/HIRS_Utils/src/main/java/hirs/utils/tpm/eventlog/events/DeviceSecurityEventDataDeviceContext.java
index 34bdd300..81d6c6bb 100644
--- a/HIRS_Utils/src/main/java/hirs/utils/tpm/eventlog/events/DeviceSecurityEventDataDeviceContext.java
+++ b/HIRS_Utils/src/main/java/hirs/utils/tpm/eventlog/events/DeviceSecurityEventDataDeviceContext.java
@@ -1,6 +1,7 @@
 package hirs.utils.tpm.eventlog.events;
 
 import hirs.utils.HexUtils;
+import hirs.utils.tpm.eventlog.spdm.SpdmMeasurementBlock;
 import hirs.utils.tpm.eventlog.uefi.UefiConstants;
 import lombok.Getter;
 
@@ -21,42 +22,39 @@ import java.nio.charset.StandardCharsets;
 public class DeviceSecurityEventDataDeviceContext {
 
     /**
-     * Contains the human-readable info inside the Device Security Event Data Device Context structure.
+     * SPDM Measurement Block.
      */
-    @Getter
-    private String dSEDdeviceContextInfo = "";
-    /**
-     * PCI Version.
-     */
-    @Getter
-    private String pciVersion = "";
-    /**
-     * PCI Length.
-     */
-    @Getter
-    private String pciLength = "";
+    private DeviceSecurityEventDataPciContext deviceSecurityEventDataPciContext = null;
 
     /**
      * DeviceSecurityEventDataDeviceContext Constructor.
      *
-     * @param dSEDbytes byte array holding the DeviceSecurityEventData.
+     * @param dSEDdeviceContextBytes byte array holding the DeviceSecurityEventData.
      */
-    public DeviceSecurityEventDataDeviceContext(final byte[] dSEDbytes, int byteStartOffset) {
+    public DeviceSecurityEventDataDeviceContext(final byte[] dSEDdeviceContextBytes) {
 
-        int byteOffset = byteStartOffset;
+        byte[] dSEDpciContextLengthBytes = new byte[2];
+        System.arraycopy(dSEDdeviceContextBytes, 2, dSEDpciContextLengthBytes, 0, 2);
+        int dSEDpciContextLength = HexUtils.leReverseInt(dSEDpciContextLengthBytes);
 
-        byte[] pciVersionBytes = new byte[UefiConstants.SIZE_16];
-        System.arraycopy(dSEDbytes, byteOffset, pciVersionBytes, 0, UefiConstants.SIZE_16);
-        pciVersion = new String(pciVersionBytes, StandardCharsets.UTF_8)
-                .substring(0, UefiConstants.SIZE_15);
+        byte[] dSEDpciContextBytes = new byte[dSEDpciContextLength];
+        System.arraycopy(dSEDdeviceContextBytes, 0, dSEDpciContextBytes, 0, dSEDpciContextLength);
+        deviceSecurityEventDataPciContext = new DeviceSecurityEventDataPciContext(dSEDpciContextBytes);
 
-        byteOffset += UefiConstants.SIZE_16;
-        byte[] pciLengthBytes = new byte[UefiConstants.SIZE_4];
-        System.arraycopy(dSEDbytes, byteOffset, pciLengthBytes, 0,
-                UefiConstants.SIZE_16);
-        pciLength = HexUtils.byteArrayToHexString(pciLengthBytes);
+        //TODO add USB context
+    }
 
+    /**
+     * Returns a human readable description of the data within this structure.
+     *
+     * @return a description of this structure..
+     */
+    public String toString() {
+        String dSEDdeviceContextInfo = "";
 
+        dSEDdeviceContextInfo += deviceSecurityEventDataPciContext.toString();
+
+        return dSEDdeviceContextInfo;
     }
 }
 
diff --git a/HIRS_Utils/src/main/java/hirs/utils/tpm/eventlog/events/DeviceSecurityEventDataHeader.java b/HIRS_Utils/src/main/java/hirs/utils/tpm/eventlog/events/DeviceSecurityEventDataHeader.java
index 955a353c..c8a9ecf7 100644
--- a/HIRS_Utils/src/main/java/hirs/utils/tpm/eventlog/events/DeviceSecurityEventDataHeader.java
+++ b/HIRS_Utils/src/main/java/hirs/utils/tpm/eventlog/events/DeviceSecurityEventDataHeader.java
@@ -48,8 +48,13 @@ public class DeviceSecurityEventDataHeader extends DeviceSecurityEventDataHeader
     /**
      * SPDM Measurement Block.
      */
-    private SpdmMeasurementBlock spdmMeasurementBlock;
+    private SpdmMeasurementBlock spdmMeasurementBlock = null;
 
+    /**
+     * DeviceSecurityEventDataHeader Constructor.
+     *
+     * @param dSEDbytes byte array holding the DeviceSecurityEventData.
+     */
     public DeviceSecurityEventDataHeader(final byte[] dSEDbytes) throws UnsupportedEncodingException {
 
         super(dSEDbytes);
@@ -92,15 +97,15 @@ public class DeviceSecurityEventDataHeader extends DeviceSecurityEventDataHeader
 //        }
 
         int devPathLenStartByte = 28 + sizeOfSpdmMeasBlock;
-        extractDevicePath(dSEDbytes, devPathLenStartByte);
+        extractDevicePathAndFinalSize(dSEDbytes, devPathLenStartByte);
 
     }
 
 
     /**
-     * Returns a human readable description of the data within this event.
+     * Returns a human readable description of the data within this structure.
      *
-     * @return a description of this event..
+     * @return a description of this structure.
      */
     public String toString() {
         String dsedHeaderInfo = "";
diff --git a/HIRS_Utils/src/main/java/hirs/utils/tpm/eventlog/events/DeviceSecurityEventDataHeaderBase.java b/HIRS_Utils/src/main/java/hirs/utils/tpm/eventlog/events/DeviceSecurityEventDataHeaderBase.java
index 763a163f..3dfe8c42 100644
--- a/HIRS_Utils/src/main/java/hirs/utils/tpm/eventlog/events/DeviceSecurityEventDataHeaderBase.java
+++ b/HIRS_Utils/src/main/java/hirs/utils/tpm/eventlog/events/DeviceSecurityEventDataHeaderBase.java
@@ -107,9 +107,8 @@ public abstract class DeviceSecurityEventDataHeaderBase {
 
     }
 
-
     /**
-     * DeviceSecurityEventDataHeader Constructor.
+     * DeviceSecurityEventDataHeaderBase Constructor.
      *
      * @param dSEDbytes byte array holding the DeviceSecurityEventData.
      */
@@ -138,7 +137,7 @@ public abstract class DeviceSecurityEventDataHeaderBase {
         deviceType = HexUtils.leReverseInt(deviceTypeBytes);
     }
 
-    public void extractDevicePath(final byte[] dSEDbytes, int startByte)
+    public void extractDevicePathAndFinalSize(final byte[] dSEDbytes, int startByte)
             throws UnsupportedEncodingException {
 
         // get the device path length
@@ -156,6 +155,8 @@ public abstract class DeviceSecurityEventDataHeaderBase {
             devicePath = new UefiDevicePath(devPathBytes);
             devicePathValid = true;
         }
+
+        dSEDheaderByteSize = startByte + devicePathLength;
     }
 
     /**
@@ -184,9 +185,9 @@ public abstract class DeviceSecurityEventDataHeaderBase {
     }
 
     /**
-     * Returns a human readable description of the data within this event.
+     * Returns a human readable description of the data within this structure.
      *
-     * @return a description of this event..
+     * @return a description of this structure.
      */
     public String headerBaseToString() {
         String dsedHeaderInfo = "";
@@ -197,7 +198,7 @@ public abstract class DeviceSecurityEventDataHeaderBase {
             dsedHeaderInfo += devicePath;
         }
         else {
-            dsedHeaderInfo += "\n   SPDM Device Path = Uknown or invalid";
+            dsedHeaderInfo += "\n   SPDM Device Path = Unknown or invalid";
         }
 
         return dsedHeaderInfo;
diff --git a/HIRS_Utils/src/main/java/hirs/utils/tpm/eventlog/events/DeviceSecurityEventDataPciContext.java b/HIRS_Utils/src/main/java/hirs/utils/tpm/eventlog/events/DeviceSecurityEventDataPciContext.java
new file mode 100644
index 00000000..e312b7a3
--- /dev/null
+++ b/HIRS_Utils/src/main/java/hirs/utils/tpm/eventlog/events/DeviceSecurityEventDataPciContext.java
@@ -0,0 +1,111 @@
+package hirs.utils.tpm.eventlog.events;
+
+import hirs.utils.HexUtils;
+import hirs.utils.tpm.eventlog.spdm.SpdmHa;
+import lombok.Getter;
+
+public class DeviceSecurityEventDataPciContext {
+
+    /**
+     * PCI Version.
+     */
+    @Getter
+    private int pciVersion = 0;
+    /**
+     * PCI Length.
+     */
+    @Getter
+    private int pciLength = 0;
+    /**
+     * PCI Vendor ID.
+     */
+    @Getter
+    private int pciVendorId = 0;
+    /**
+     * PCI Device ID.
+     */
+    @Getter
+    private int pciDeviceId = 0;
+    /**
+     * PCI Revision ID.
+     */
+    @Getter
+    private int pciRevisionId = 0;
+    /**
+     * PCI Class Code.
+     */
+    @Getter
+    private int pciClassCode = 0;
+    /**
+     * PCI Subsystem Vendor ID.
+     */
+    @Getter
+    private int pciSubsystemVendorId = 0;
+    /**
+     * PCI Subsystem ID.
+     */
+    @Getter
+    private int pciSubsystemId = 0;
+
+    /**
+     * DeviceSecurityEventDataPciContext Constructor.
+     *
+     * @param dSEDpciContextBytes byte array holding the DeviceSecurityEventDataPciContext.
+     */
+    public DeviceSecurityEventDataPciContext(final byte[] dSEDpciContextBytes) {
+
+        byte[] pciVersionBytes = new byte[2];
+        System.arraycopy(dSEDpciContextBytes, 0, pciVersionBytes, 0, 2);
+        pciVersion = HexUtils.leReverseInt(pciVersionBytes);
+
+        byte[] pciLengthBytes = new byte[2];
+        System.arraycopy(dSEDpciContextBytes, 2, pciLengthBytes, 0, 2);
+        pciLength = HexUtils.leReverseInt(pciLengthBytes);
+
+        byte[] pciVendorIdBytes = new byte[2];
+        System.arraycopy(dSEDpciContextBytes, 4, pciVendorIdBytes, 0, 2);
+        pciVendorId = HexUtils.leReverseInt(pciVendorIdBytes);
+
+        byte[] pciDeviceIdBytes = new byte[2];
+        System.arraycopy(dSEDpciContextBytes, 6, pciDeviceIdBytes, 0, 2);
+        pciDeviceId = HexUtils.leReverseInt(pciDeviceIdBytes);
+
+        byte[] pciRevisionIdBytes = new byte[1];
+        System.arraycopy(dSEDpciContextBytes, 8, pciRevisionIdBytes, 0, 1);
+        pciRevisionId = HexUtils.leReverseInt(pciRevisionIdBytes);
+
+        byte[] pciClassCodeBytes = new byte[3];
+        System.arraycopy(dSEDpciContextBytes, 9, pciClassCodeBytes, 0, 3);
+        pciClassCode = HexUtils.leReverseInt(pciClassCodeBytes);
+
+        byte[] pciSubsystemVendorIdBytes = new byte[2];
+        System.arraycopy(dSEDpciContextBytes, 12, pciSubsystemVendorIdBytes, 0, 2);
+        pciSubsystemVendorId = HexUtils.leReverseInt(pciSubsystemVendorIdBytes);
+
+        byte[] pciSubsystemIdBytes = new byte[2];
+        System.arraycopy(dSEDpciContextBytes, 14, pciSubsystemIdBytes, 0, 2);
+        pciSubsystemId = HexUtils.leReverseInt(pciSubsystemIdBytes);
+
+    }
+
+    /**
+     * Returns a human readable description of the data within this structure.
+     *
+     * @return a description of this structure..
+     */
+    public String toString() {
+        String dSEDpciContextInfo = "";
+
+        dSEDpciContextInfo += "\n   DeviceSecurityEventData - PCI Context";
+        dSEDpciContextInfo += "\n      Version = " + pciVersion;
+        dSEDpciContextInfo += "\n      Length = " + pciLength;
+        dSEDpciContextInfo += "\n      VendorID = " + pciVendorId;
+        dSEDpciContextInfo += "\n      DeviceID = " + pciDeviceId;
+        dSEDpciContextInfo += "\n      RevisionID = " + pciRevisionId;
+        dSEDpciContextInfo += "\n      ClassCode = " + pciClassCode;
+        dSEDpciContextInfo += "\n      SubsystemVendorID = " + pciSubsystemVendorId;
+        dSEDpciContextInfo += "\n      SubsystemID = " + pciSubsystemId;
+
+        return dSEDpciContextInfo;
+    }
+}
diff --git a/HIRS_Utils/src/main/java/hirs/utils/tpm/eventlog/events/EvEfiSpdmFirmwareBlob.java b/HIRS_Utils/src/main/java/hirs/utils/tpm/eventlog/events/EvEfiSpdmFirmwareBlob.java
index 17f46239..f0eb9e4c 100644
--- a/HIRS_Utils/src/main/java/hirs/utils/tpm/eventlog/events/EvEfiSpdmFirmwareBlob.java
+++ b/HIRS_Utils/src/main/java/hirs/utils/tpm/eventlog/events/EvEfiSpdmFirmwareBlob.java
@@ -97,11 +97,8 @@ public class EvEfiSpdmFirmwareBlob {
      * @return Human readable description of this event.
      */
     public String toString() {
-//        String spdmInfo = "";
         if (bDeviceSecurityEventData) {
             spdmInfo = "   Signature = SPDM Device Sec" + spdmInfo;
-//            spdmInfo += "   Signature = SPDM Device Sec";
-//            spdmInfo += deviceSecurityEventData.toString();
         } else {
             spdmInfo = "EV_EFI_SPDM_FIRMWARE_BLOB event named " + signature
                     + " encountered but support for processing it has not been added to this application.\n";