From a1534a9c7bc89b8b66d8c2b8f164de00a75a0209 Mon Sep 17 00:00:00 2001
From: iadgovuser58 <124906646+iadgovuser58@users.noreply.github.com>
Date: Wed, 10 Apr 2024 11:46:37 -0400
Subject: [PATCH] SPDM processing

---
 .../events/DeviceSecurityEventData.java       | 160 ++++++++----------
 .../DeviceSecurityEventDataDeviceContext.java |  40 +++++
 .../events/DeviceSecurityEventDataHeader.java |  95 +++++------
 .../DeviceSecurityEventDataPciContext.java    |  22 ---
 .../events/EvEfiSpdmFirmwareBlob.java         |  15 +-
 5 files changed, 167 insertions(+), 165 deletions(-)
 delete 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 c2d74566..5d98b8bd 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
@@ -3,6 +3,7 @@ package hirs.utils.tpm.eventlog.events;
 import hirs.utils.HexUtils;
 import hirs.utils.tpm.eventlog.TcgTpmtHa;
 import hirs.utils.tpm.eventlog.uefi.UefiConstants;
+import jakarta.persistence.criteria.CriteriaBuilder;
 import lombok.Getter;
 
 import java.nio.charset.StandardCharsets;
@@ -11,25 +12,33 @@ import java.util.List;
 
 
 /**
- * Class to process the DEVICE_SECURITY_EVENT_DATA event per PFP.
- * DEVICE_SECURITY_EVENT_DATA has 2 structures:
- *    1) DEVICE_SECURITY_EVENT_DATA_HEADER
- *    2) DEVICE_SECURITY_EVENT_DATA_DEVICE_CONTEXT
- * DEVICE_SECURITY_EVENT_DATA_HEADER
- *    The first 16 bytes of the event data header MUST be a String based identifier (Signature),
- *    NUL-terminated. The only currently defined Signature is "SPDM Device Sec" which implies
- *    the event data is a DEVICE_SECURITY_EVENT_DATA. DEVICE_SECURITY_EVENT_DATA_HEADER contains
- *    the measurement(s) and hash algorithm (SpdmHashAlg) identifier returned by the SPDM
- *    "GET_MEASUREMENTS" function.
- * DEVICE_SECURITY_EVENT_DATA_DEVICE_CONTEXT
- *    DEVICE_SECURITY_EVENT_DATA_DEVICE_CONTEXT is a common SPDM structure which includes the
- *       identification of the device, device vendor, subsystem, etc.
+ * Class to process the DEVICE_SECURITY_EVENT_DATA or ..DATA2 event per PFP.
+ * The event data comes in 2 forms:
+ *    1) DEVICE_SECURITY_EVENT_DATA or
+ *    2) DEVICE_SECURITY_EVENT_DATA2
+ * The first 16 bytes of the event data header MUST be a String based identifier (Signature),
+ * NUL-terminated, per PFP. The only currently defined Signature is "SPDM Device Sec", which
+ * implies the data is a DEVICE_SECURITY_EVENT_DATA or ..DATA2. The Version field indicates
+ * whether it is ..DATA or ..DATA2.
+ *
+ * DEVICE SECURITY EVENT structures defined by PFP v1.06 Rev 52:
  * <p>
  * typedef struct tdDEVICE_SECURITY_EVENT_DATA {
  * DEVICE_SECURITY_EVENT_DATA_HEADER            EventDataHeader;
  * DEVICE_SECURITY_EVENT_DATA_DEVICE_CONTEXT    DeviceContext;
  * } DEVICE_SECURITY_EVENT_DATA;
  * <p>
+ * typedef struct tdDEVICE_SECURITY_EVENT_DATA2 {
+ * DEVICE_SECURITY_EVENT_DATA_HEADER2           EventDataHeader;
+ * DEVICE_SECURITY_EVENT_DATA_SUB_HEADER        EventDataSubHeader;
+ * DEVICE_SECURITY_EVENT_DATA_DEVICE_CONTEXT    DeviceContext;
+ * } DEVICE_SECURITY_EVENT_DATA;
+ * <p>
+ * typedef struct tdDEVICE_SECURITY_EVENT_DATA_DEVICE_CONTEXT {
+ * DEVICE_SECURITY_EVENT_DATA_PCI_CONTEXT        PciContext;
+ * DEVICE_SECURITY_EVENT_DATA_USB_CONTEXT        UsbContext;
+ * } DEVICE_SECURITY_EVENT_DATA_DEVICE_CONTEXT;
+ * <p>
  * Notes: Parses event data for an DEVICE_SECURITY_EVENT_DATA per PFP v1.06 Rev52 Table 20.
  * 1. Has an EventType of EV_EFI_SPDM_FIRMWARE_BLOB (0x800000E1)
  * 2. Digest of 48 bytes
@@ -37,104 +46,79 @@ import java.util.List;
  * 4. First 16 bytes of the structure header is an ASCII "SPDM Device Sec"
  */
 public class DeviceSecurityEventData {
-//    /**
-//     * Minor Version.
-//     */
-//    @Getter
-//    private String versionMinor = "";
-//    /**
-//     * Major Version.
-//     */
-//    @Getter
-//    private String versionMajor = "";
-//    /**
-//     * Specification errata version.
-//     */
-//    @Getter
-//    private String errata = "";
+
     /**
      * Signature (text) data.
      */
     @Getter
     private String signature = "";
     /**
-     * Platform class.
+     * 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 String version = "";
-//    /**
-//     * Algorithm count.
-//     */
-//    @Getter
-//    private int numberOfAlg = 0;
-//    /**
-//     * True if event log uses Crypto Agile format.
-//     */
-//    @Getter
-//    private boolean cryptoAgile = false;
-//    /**
-//     * Algorithm list.
-//     */
-//    private List<String> algList;
+    private DeviceSecurityEventDataHeader dSEDheader = null;
+    /**
+     * DeviceSecurityEventDataSubHeader Object.
+     */
+    @Getter
+    private DeviceSecurityEventDataHeader dSEDsubHeader = null;
+    /**
+     * DeviceSecurityEventDataDeviceContext Object.
+     */
+    @Getter
+    private DeviceSecurityEventDataDeviceContext dSEDdeviceContext = null;
 
     /**
      * DeviceSecurityEventData Constructor.
      *
-     * @param deviceSecurityEventDataBytes byte array holding the spec ID Event.
+     * @param dSEDbytes byte array holding the DeviceSecurityEventData.
      */
-    public DeviceSecurityEventData(final byte[] deviceSecurityEventDataBytes) {
-//        algList = new ArrayList<>();
+    public DeviceSecurityEventData(final byte[] dSEDbytes) {
+
         byte[] signatureBytes = new byte[UefiConstants.SIZE_16];
-        System.arraycopy(deviceSecurityEventDataBytes, 0, signatureBytes, 0, 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);
 
         byte[] versionBytes = new byte[UefiConstants.SIZE_4];
-        System.arraycopy(deviceSecurityEventDataBytes, UefiConstants.OFFSET_16, versionBytes, 0,
+        System.arraycopy(dSEDbytes, UefiConstants.OFFSET_16, versionBytes, 0,
                 UefiConstants.SIZE_4);
-        version = HexUtils.byteArrayToHexString(versionBytes);
+        String version = HexUtils.byteArrayToHexString(versionBytes);
+
+        // If version is 0x01, the event is a DEVICE_SECURITY_EVENT_DATA
+        // If version is 0x02, the event is a DEVICE_SECURITY_EVENT_DATA2
+        int byteOffset = 0;
+        dSEDheader = new DeviceSecurityEventDataHeader(dSEDbytes);
+        byteOffset = dSEDheader.getDSEDheaderByteSize();
+        if (version == "2") {
+//            dSEDsubHeader = new DeviceSecurityEventDataSubHeader(dSEDbytes,byteOffset);
+//            byteOffset = dSEDheader.getDSEDsubHeaderByteSize();
+        }
+        dSEDdeviceContext = new DeviceSecurityEventDataDeviceContext(dSEDbytes, byteOffset);
 
         if (version == "1") {
-
+            dSEDinfo =+
+                    dSEDataHeader.getDSEDheaderInfo();
+            dSEDinfo =+
+                    dSEDdeviceContext.getdSEDdeviceContextInfo();
         } else if (version == "2") {
-
+            dSEDinfo =+
+                    dSEDheader.getDSEDheaderInfo();
+            dSEDinfo =+
+                    dSEDsubHeader.getDSEDsubHeaderInfo();
+            dSEDinfo =+
+                    dSEDdeviceContext.getDSEDdeviceContextInfo();
         }
-
-//        byte[] platformClassBytes = new byte[UefiConstants.SIZE_4];
-//        System.arraycopy(efiSpecId, UefiConstants.OFFSET_16, platformClassBytes, 0,
-//                UefiConstants.SIZE_4);
-//        platformClass = HexUtils.byteArrayToHexString(platformClassBytes);
-//
-//        byte[] specVersionMinorBytes = new byte[1];
-//        System.arraycopy(efiSpecId, UefiConstants.OFFSET_20, specVersionMinorBytes, 0, 1);
-//        versionMinor = HexUtils.byteArrayToHexString(specVersionMinorBytes);
-//
-//        byte[] specVersionMajorBytes = new byte[1];
-//        System.arraycopy(efiSpecId, UefiConstants.OFFSET_21, specVersionMajorBytes, 0, 1);
-//        versionMajor = HexUtils.byteArrayToHexString(specVersionMajorBytes);
-//
-//        byte[] specErrataBytes = new byte[1];
-//        System.arraycopy(efiSpecId, UefiConstants.OFFSET_22, specErrataBytes, 0, 1);
-//        errata = HexUtils.byteArrayToHexString(specErrataBytes);
-//
-//        byte[] numberOfAlgBytes = new byte[UefiConstants.SIZE_4];
-//        System.arraycopy(efiSpecId, UefiConstants.OFFSET_24, numberOfAlgBytes, 0,
-//                UefiConstants.SIZE_4);
-//        numberOfAlg = HexUtils.leReverseInt(numberOfAlgBytes);
-//
-//        byte[] algorithmIDBytes = new byte[UefiConstants.SIZE_2];
-//        int algLocation = UefiConstants.SIZE_28;
-//        for (int i = 0; i < numberOfAlg; i++) {
-//            System.arraycopy(efiSpecId, algLocation + UefiConstants.OFFSET_4 * i, algorithmIDBytes,
-//                    0, UefiConstants.SIZE_2);
-//            String alg = TcgTpmtHa.tcgAlgIdToString(HexUtils.leReverseInt(algorithmIDBytes));
-//            algList.add(alg);
-//        }
-//        if ((algList.size() == 1) && (algList.get(0).compareTo("SHA1") == 0)) {
-//            cryptoAgile = false;
-//        } else {
-//            cryptoAgile = true;
-//        }
     }
 }
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 34b9b28a..286ebc31 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,5 +1,11 @@
 package hirs.utils.tpm.eventlog.events;
 
+import hirs.utils.HexUtils;
+import hirs.utils.tpm.eventlog.uefi.UefiConstants;
+import lombok.Getter;
+
+import java.nio.charset.StandardCharsets;
+
 /**
  * Class to process the DEVICE_SECURITY_EVENT_DATA_DEVICE_CONTEXT event per PFP.
  * DEVICE_SECURITY_EVENT_DATA_DEVICE_CONTEXT is a common SPDM structure which includes the
@@ -13,5 +19,39 @@ package hirs.utils.tpm.eventlog.events;
  * <p>
  */
 public class DeviceSecurityEventDataDeviceContext {
+
+    /**
+     * Contains the human-readable info inside the Device Security Event Data Device Context structure.
+     */
+    @Getter
+    private String dSEDdeviceContextInfo = "";
+    /**
+     * PCI Version.
+     */
+    @Getter
+    private String pciVersion = "";
+    /**
+     * PCI Length.
+     */
+    @Getter
+    private String pciLength = "";
+
+    public DeviceSecurityEventDataDeviceContext(final byte[] dSEDbytes, int byteStartOffset) {
+
+        int byteOffset = byteStartOffset;
+
+        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);
+
+        byteOffset += UefiConstants.SIZE_16;
+        byte[] pciLengthBytes = new byte[UefiConstants.SIZE_4];
+        System.arraycopy(dSEDbytes, byteOffset, pciLengthBytes, 0,
+                UefiConstants.SIZE_16);
+        pciLength = HexUtils.byteArrayToHexString(pciLengthBytes);
+
+
+    }
 }
 
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 1ad91963..28348eeb 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
@@ -10,14 +10,15 @@ import java.util.ArrayList;
 import java.util.List;
 
 /**
- * Class to process the DEVICE_SECURITY_EVENT_DATA_HEADER per PFP.
+ * Class to process the DEVICE_SECURITY_EVENT_DATA_HEADER or ..HEADER2 per PFP.
  * The first 16 bytes of the event data header MUST be a String based identifier (Signature),
- * NUL-terminated. The only currently defined Signature is "SPDM Device Sec" which implies
- * the event data is a DEVICE_SECURITY_EVENT_DATA. DEVICE_SECURITY_EVENT_DATA_HEADER contains
- * the measurement(s) and hash algorithm (SpdmHashAlg) identifier returned by the SPDM
- * "GET_MEASUREMENTS" function.
+ * NUL-terminated, per PFP. The only currently defined Signature is "SPDM Device Sec",
+ * which implies the data is a DEVICE_SECURITY_EVENT_DATA or ..DATA2.
+ * DEVICE_SECURITY_EVENT_DATA_HEADER contains the measurement(s) and hash algorithm identifier
+ * returned by the SPDM "GET_MEASUREMENTS" function.
+ *
+ * HEADERS defined by PFP v1.06 Rev 52:
  * <p>
- * PFP v1.06 Rev 52:
  * typedef struct tdDEVICE_SECURITY_EVENT_DATA_HEADER {
  *      UINT8                           Signature[16];
  *      UINT16                          Version;
@@ -29,8 +30,22 @@ import java.util.List;
  *      UNIT8                           DevicePath[DevicePathLength]
  * } DEVICE_SECURITY_EVENT_DATA_HEADER;
  * <p>
- * SPDM_MEASUREMENT_BLOCK:
- * SPDM v1.03, Sect 10.11.1, Table 53:
+ * typedef struct tdDEVICE_SECURITY_EVENT_DATA_HEADER2 {
+ *      UINT8                           Signature[16];
+ *      UINT16                          Version;
+ *      UINT8                           AuthState;
+ *      UINT8                           Reserved;
+ *      UINT32                          Length;
+ *      UINT32                          DeviceType;
+ *      UINT32                          SubHeaderType;
+ *      UINT32                          SubHeaderLength;
+ *      UINT32                          SubHeaderUID;
+ *      UINT64                          DevicePathLength;
+ *      UNIT8                           DevicePath[DevicePathLength]
+ * } DEVICE_SECURITY_EVENT_DATA_HEADER2;
+ *
+ * SPDM_MEASUREMENT_BLOCK and contents defined by SPDM v1.03, Sect 10.11.1, Table 53 and 54:
+ * <p>
  * Measurement block format {
  *      Index                           1 byte;
  *      MeasurementSpec                 1 byte;
@@ -38,7 +53,6 @@ import java.util.List;
  *      Measurement                     <MeasurementSize> bytes;
  * }
  * <p>
- * SPDM v1.03, SPDM 10.11.1, Table 54:
  * DMTF measurement spec format {
  *      DMTFSpecMeasurementValueType    1 byte;
  *      DMTFSpecMeasurementValueSize    2 bytes;
@@ -58,45 +72,28 @@ import java.util.List;
  * <p>
  */
 public class DeviceSecurityEventDataHeader {
-//    /**
-//     * Minor Version.
-//     */
-//    @Getter
-//    private String versionMinor = "";
-//    /**
-//     * Major Version.
-//     */
-//    @Getter
-//    private String versionMajor = "";
-//    /**
-//     * Specification errata version.
-//     */
-//    @Getter
-//    private String errata = "";
-//    /**
-//     * Signature (text) data.
-//     */
-//    @Getter
-//    private String signature = "";
-//    /**
-//     * Platform class.
-//     */
-//    @Getter
-//    private String platformClass = "";
-//    /**
-//     * Algorithm count.
-//     */
-//    @Getter
-//    private int numberOfAlg = 0;
-//    /**
-//     * True if event log uses Crypto Agile format.
-//     */
-//    @Getter
-//    private boolean cryptoAgile = false;
-//    /**
-//     * Algorithm list.
-//     */
-//    private List<String> algList;
+
+    /**
+     * Signature (text) data.
+     */
+    @Getter
+    private String signature = "";
+    /**
+     * Version determines data structure used (..DATA or ..DATA2),
+     * which determines whether ..HEADER or ..HEADER2 is used
+     */
+    @Getter
+    private String version = "";
+    /**
+     * Contains the human-readable info inside the Device Security Event.
+     */
+    @Getter
+    private String dSEDheaderInfo = "";
+    /**
+     * Contains the size (in bytes) of the Header.
+     */
+    @Getter
+    private Integer dSEDheaderByteSize = 0;
 //
 //    /**
 //     * EvEfiSpecIdEvent Constructor.
@@ -164,4 +161,6 @@ public class DeviceSecurityEventDataHeader {
 //        }
 //        return specInfo;
 //    }
+
+
 }
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
deleted file mode 100644
index 174dab66..00000000
--- a/HIRS_Utils/src/main/java/hirs/utils/tpm/eventlog/events/DeviceSecurityEventDataPciContext.java
+++ /dev/null
@@ -1,22 +0,0 @@
-package hirs.utils.tpm.eventlog.events;
-
-
-/**
- * Class to process the DEVICE_SECURITY_EVENT_DATA_PCI_CONTEXT event per PFP.
- * DEVICE_SECURITY_EVENT_DATA_PCI_CONTEXT is an SPDM structure which includes the
- * identification of the device, device vendor, subsystem, etc. for a PCI device.
- * <p>
- * typedef struct DEVICE_SECURITY_EVENT_DATA_PCI_CONTEXT {
- *      UINT16                          Version;
- *      UINT16                          Length;
- *      UINT16                          VendorId;
- *      UINT16                          DeviceId;
- *      UINT8                           RevisionID;
- *      UINT8                           ClassCode[3];
- *      UINT16                          SubsystemVendorID;
- *      UINT16                          SubsystemID;
- * } DEVICE_SECURITY_EVENT_DATA_PCI_CONTEXT;
- * <p>
- */
-public class DeviceSecurityEventDataPciContext {
-}
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 42920012..f5c49860 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
@@ -12,8 +12,8 @@ import java.util.List;
 
 /**
  * Class to process the EV_EFI_SPDM_FIRMWARE_BLOB event. The event field MUST be a
- *      1) DEVICE_SECURITY_EVENT_DATA or
- *      1) DEVICE_SECURITY_EVENT_DATA2
+ *    1) DEVICE_SECURITY_EVENT_DATA or
+ *    2) DEVICE_SECURITY_EVENT_DATA2
  * DEVICE_SECURITY_EVENT_DATA has 2 structures:
  *    1) DEVICE_SECURITY_EVENT_DATA_HEADER
  *    2) DEVICE_SECURITY_EVENT_DATA_DEVICE_CONTEXT, which has 2 structures
@@ -25,11 +25,12 @@ import java.util.List;
  *    3) DEVICE_SECURITY_EVENT_DATA_DEVICE_CONTEXT, which has 2 structures (see above)
  * The first 16 bytes of the event data header MUST be a String based identifier (Signature),
  * NUL-terminated, per PFP. The only currently defined Signature is "SPDM Device Sec",
- * which implies the data is a DEVICE_SECURITY_EVENT_DATA.
- * This event is used to record an extended digest for the firmware of an embedded component
- * or an add-in device that supports SPDM “GET_MEASUREMENTS” functionality. This event records
- * extended digests of SPDM GET_MEASUREMENT responses that correspond to firmware, such as
- * immutable ROM, mutable firmware, firmware version, firmware secure version number, etc.
+ * which implies the data is a DEVICE_SECURITY_EVENT_DATA or ..DATA2.
+ * The EV_EFI_SPDM_FIRMWARE_BLOB event is used to record an extended digest for the firmware of
+ * an embedded component or an add-in device that supports SPDM “GET_MEASUREMENTS” functionality.
+ * This event records extended digests of SPDM GET_MEASUREMENT responses that correspond to
+ * firmware, such as immutable ROM, mutable firmware, firmware version, firmware secure version
+ * number, etc.
  */
 public class EvEfiSpdmFirmwareBlob {