Skip to content

Commit

Permalink
Merge pull request #762 from nsacyber/v3_issue_747-spdm
Browse files Browse the repository at this point in the history
Process SPDM Event EV_EFI_SPDM_FIRMWARE_BLOB
  • Loading branch information
iadgovuser58 authored May 1, 2024
2 parents 144160d + 9f097f3 commit a418d11
Show file tree
Hide file tree
Showing 14 changed files with 1,129 additions and 0 deletions.
14 changes: 14 additions & 0 deletions HIRS_Utils/src/main/java/hirs/utils/tpm/eventlog/TpmPcrEvent.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import hirs.utils.tpm.eventlog.events.EvConstants;
import hirs.utils.tpm.eventlog.events.EvEfiGptPartition;
import hirs.utils.tpm.eventlog.events.EvEfiHandoffTable;
import hirs.utils.tpm.eventlog.events.EvEfiSpdmFirmwareBlob;
import hirs.utils.tpm.eventlog.events.EvEfiSpecIdEvent;
import hirs.utils.tpm.eventlog.events.EvEventTag;
import hirs.utils.tpm.eventlog.events.EvIPL;
Expand Down Expand Up @@ -374,6 +375,14 @@ public String getEventContentStr() {
break;
case EvConstants.EV_EFI_HCRTM_EVENT:
break;
case EvConstants.EV_EFI_SPDM_FIRMWARE_BLOB:
try {
sb.append(new EvEfiSpdmFirmwareBlob(eventContent).toString());
} catch (UnsupportedEncodingException ueEx) {
log.error(ueEx);
sb.append(ueEx.toString());
}
break;
default:
sb.append("Unknown Event found\n");
}
Expand Down Expand Up @@ -532,6 +541,9 @@ public String processEvent(final byte[] eventData, final byte[] content,
case EvConstants.EV_EFI_VARIABLE_AUTHORITY:
description += "Event Content:\n" + new UefiVariable(content).toString();
break;
case EvConstants.EV_EFI_SPDM_FIRMWARE_BLOB:
description += "Event Content:\n" + new EvEfiSpdmFirmwareBlob(content).toString();
break;
default:
description += " Unknown Event found" + "\n";
}
Expand Down Expand Up @@ -609,6 +621,8 @@ private static String eventString(final long event) {
return "EV_EFI_HCRTM_EVENT";
} else if (event == EvConstants.EV_EFI_VARIABLE_AUTHORITY) {
return "EV_EFI_VARIABLE_AUTHORITY";
} else if (event == EvConstants.EV_EFI_SPDM_FIRMWARE_BLOB) {
return "EV_EFI_SPDM_FIRMWARE_BLOB";
} else {
return "Unknown Event ID " + event + " encountered";
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
package hirs.utils.tpm.eventlog.events;

import lombok.Getter;


/**
* Abstract base class to process the DEVICE_SECURITY_EVENT_DATA or ..DATA2 event.
* Parses event data per PFP v1.06 Rev52 Tables 20 and 26.
* The event data comes in 2 forms:
* 1) DEVICE_SECURITY_EVENT_DATA or
* 2) DEVICE_SECURITY_EVENT_DATA2
* The first 2 fields of the respective headers are the same in both ..DATA and ..DATA2.
* Field 1:
* 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.
* Field 2:
* The Version field indicates whether the Device Security Event 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_DATA2;
* <p>
* typedef struct tdDEVICE_SECURITY_EVENT_DATA_HEADER or HEADER2 {
* UINT8 Signature[16];
* UINT16 Version;
* ... ...
* }
* <p>
* Notes:
* 1. Has an EventType of EV_EFI_SPDM_FIRMWARE_BLOB (0x800000E1)
* 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 DeviceSecurityEvent {

/**
* Human readable description of the data within the
* DEVICE_SECURITY_EVENT_DATA_DEVICE_CONTEXT. DEVICE can be either PCI or USB.
*/
@Getter
String deviceContextInfo = "";

/**
* DeviceSecurityEventData Default Constructor.
*
*/
public DeviceSecurityEvent() {

}

/**
* Parse the Device Context structure, can be PCI or USB based on device type field.
*
* @param dSEDbytes byte array holding the DeviceSecurityEventData.
* @param startByte starting byte of the device structure (depends on length of header).
* @param deviceType device type either PCI or USB.
*
*/
public void parseDeviceContext(final byte[] dSEDbytes, int startByte, int deviceType) {

int deviceContextLength = dSEDbytes.length - startByte;

// get the device context bytes
byte[] deviceContextBytes = new byte[deviceContextLength];
System.arraycopy(dSEDbytes, startByte, deviceContextBytes, 0,
deviceContextLength);

if (deviceType == 0) {
deviceContextInfo = "No Device Context (indicated by device type value of 0";
}
else if (deviceType == 1) {
DeviceSecurityEventDataPciContext dSEDpciContext
= new DeviceSecurityEventDataPciContext(deviceContextBytes);
deviceContextInfo = dSEDpciContext.toString();
}
//else if (deviceType == 2) {
//DeviceSecurityEventDataUsbContext dSEDusbContext
// = new DeviceSecurityEventDataUsbContext(deviceContextBytes);
//deviceContextInfo = dSEDusbContext.toString();
//deviceContextInfo = "Device type is USB - to be implemented in future";
//}
else {
deviceContextInfo = " Unknown device type; cannot process device context";
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package hirs.utils.tpm.eventlog.events;

import lombok.Getter;
import java.io.UnsupportedEncodingException;

/**
* Class to process DEVICE_SECURITY_EVENT_DATA.
* Parses event data per PFP v1.06 Rev52 Table 20.
* <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>
*/
public class DeviceSecurityEventData extends DeviceSecurityEvent {

/**
* DeviceSecurityEventDataHeader Object.
*/
@Getter
private DeviceSecurityEventDataHeader dsedHeader = null;

/**
* DeviceSecurityEventData Constructor.
*
* @param dSEDbytes byte array holding the DeviceSecurityEventData.
*/
public DeviceSecurityEventData(final byte[] dSEDbytes) throws UnsupportedEncodingException {
dsedHeader = new DeviceSecurityEventDataHeader(dSEDbytes);
parseDeviceContext(dSEDbytes, dsedHeader.getDSEDheaderByteSize(), dsedHeader.getDeviceType());
}

/**
* 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 += getDeviceContextInfo();
return dsedInfo;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package hirs.utils.tpm.eventlog.events;

import lombok.Getter;

// TODO Placeholder class to be implemented upon getting test pattern
/**
* Class to process DEVICE_SECURITY_EVENT_DATA2.
* Parses event data per PFP v1.06 Rev52 Table 26.
* <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_DATA2;
* <p>
*/
public class DeviceSecurityEventData2 extends DeviceSecurityEvent {

/**
* DeviceSecurityEventDataHeader Object.
*/
@Getter
private DeviceSecurityEventDataHeader2 dsedHeader2 = null;

/**
* DeviceSecurityEventData2 Constructor.
*
* @param dSEDbytes byte array holding the DeviceSecurityEventData2.
*/
public DeviceSecurityEventData2(final byte[] dSEDbytes) {

dsedHeader2 = new DeviceSecurityEventDataHeader2(dSEDbytes);
// get subheader
parseDeviceContext(dSEDbytes, dsedHeader2.getDSEDheaderByteSize(), dsedHeader2.getDeviceType());
}

/**
* Returns a human readable description of the data within this structure.
*
* @return a description of this structure.
*/
public String toString() {
String dsedInfo = "";
return dsedInfo;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
package hirs.utils.tpm.eventlog.events;

import hirs.utils.HexUtils;
import lombok.Getter;

/**
* 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
* identification of the device, device vendor, subsystem, etc. Device can be either a PCI
* or USB connection.
* <p>
* typedef union 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>
*/
public abstract class DeviceSecurityEventDataDeviceContext {

/**
* PCI Version.
*/
@Getter
private int version = 0;
/**
* PCI Length.
*/
@Getter
private int length = 0;

/**
* DeviceSecurityEventDataDeviceContext Constructor.
*
* @param dSEDdeviceContextBytes byte array holding the DeviceSecurityEventData.
*/
public DeviceSecurityEventDataDeviceContext(final byte[] dSEDdeviceContextBytes) {

byte[] pciVersionBytes = new byte[2];
System.arraycopy(dSEDdeviceContextBytes, 0, pciVersionBytes, 0, 2);
version = HexUtils.leReverseInt(pciVersionBytes);

byte[] pciLengthBytes = new byte[2];
System.arraycopy(dSEDdeviceContextBytes, 2, pciLengthBytes, 0, 2);
length = HexUtils.leReverseInt(pciLengthBytes);
}

/**
* Returns a human readable description of the data common to device context structures.
*
* @return a description of this structure..
*/
public String toString() {
String dSEDdeviceContextCommonInfo = "";

dSEDdeviceContextCommonInfo += "\n DeviceSecurityEventData Device Info:";
dSEDdeviceContextCommonInfo += "\n Device Structure Version = " + version;

return dSEDdeviceContextCommonInfo;
}

}

Loading

0 comments on commit a418d11

Please sign in to comment.