mirror of
https://github.com/nsacyber/HIRS.git
synced 2024-12-21 05:53:27 +00:00
Merge pull request #795 from nsacyber/v3_issue_793-spdm
Add SPDM Events Part 3
This commit is contained in:
commit
b4225f152f
@ -391,12 +391,7 @@ public class TpmPcrEvent {
|
|||||||
break;
|
break;
|
||||||
case EvConstants.EV_EFI_SPDM_FIRMWARE_BLOB:
|
case EvConstants.EV_EFI_SPDM_FIRMWARE_BLOB:
|
||||||
case EvConstants.EV_EFI_SPDM_FIRMWARE_CONFIG:
|
case EvConstants.EV_EFI_SPDM_FIRMWARE_CONFIG:
|
||||||
try {
|
|
||||||
sb.append(new EvEfiSpdmDeviceSecurityEvent(eventContent).toString());
|
sb.append(new EvEfiSpdmDeviceSecurityEvent(eventContent).toString());
|
||||||
} catch (UnsupportedEncodingException ueEx) {
|
|
||||||
log.error(ueEx);
|
|
||||||
sb.append(ueEx.toString());
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
sb.append("Unknown Event found\n");
|
sb.append("Unknown Event found\n");
|
||||||
@ -560,7 +555,9 @@ public class TpmPcrEvent {
|
|||||||
case EvConstants.EV_EFI_HCRTM_EVENT:
|
case EvConstants.EV_EFI_HCRTM_EVENT:
|
||||||
break;
|
break;
|
||||||
case EvConstants.EV_EFI_SPDM_FIRMWARE_BLOB:
|
case EvConstants.EV_EFI_SPDM_FIRMWARE_BLOB:
|
||||||
description += "Event Content:\n" + new EvEfiSpdmDeviceSecurityEvent(content).toString();
|
EvEfiSpdmDeviceSecurityEvent tempp = new EvEfiSpdmDeviceSecurityEvent(content);
|
||||||
|
description += "Event Content:\n" + tempp.toString();
|
||||||
|
// description += "Event Content:\n" + new EvEfiSpdmDeviceSecurityEvent(content).toString();
|
||||||
break;
|
break;
|
||||||
case EvConstants.EV_EFI_SPDM_FIRMWARE_CONFIG:
|
case EvConstants.EV_EFI_SPDM_FIRMWARE_CONFIG:
|
||||||
description += "Event Content:\n" + new EvEfiSpdmDeviceSecurityEvent(content).toString();
|
description += "Event Content:\n" + new EvEfiSpdmDeviceSecurityEvent(content).toString();
|
||||||
|
@ -1,6 +1,11 @@
|
|||||||
package hirs.utils.tpm.eventlog.events;
|
package hirs.utils.tpm.eventlog.events;
|
||||||
|
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
|
||||||
|
import static hirs.utils.tpm.eventlog.events.DeviceSecurityEventHeader.DEVICE_TYPE_NONE;
|
||||||
|
import static hirs.utils.tpm.eventlog.events.DeviceSecurityEventHeader.DEVICE_TYPE_PCI;
|
||||||
|
import static hirs.utils.tpm.eventlog.events.DeviceSecurityEventHeader.DEVICE_TYPE_USB;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -51,7 +56,20 @@ import lombok.Getter;
|
|||||||
public abstract class DeviceSecurityEvent {
|
public abstract class DeviceSecurityEvent {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Human readable description of the data within the
|
* DeviceSecurityEventDataContext Object.
|
||||||
|
*/
|
||||||
|
@Getter
|
||||||
|
private DeviceSecurityEventDataDeviceContext dsedDevContext = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Device type.
|
||||||
|
*/
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
private int deviceType = -1;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Human-readable description of the data within the
|
||||||
* DEVICE_SECURITY_EVENT_DATA_DEVICE_CONTEXT. DEVICE can be either PCI or USB.
|
* DEVICE_SECURITY_EVENT_DATA_DEVICE_CONTEXT. DEVICE can be either PCI or USB.
|
||||||
*/
|
*/
|
||||||
@Getter
|
@Getter
|
||||||
@ -68,34 +86,25 @@ public abstract class DeviceSecurityEvent {
|
|||||||
/**
|
/**
|
||||||
* Parse the Device Context structure, can be PCI or USB based on device type field.
|
* Parse the Device Context structure, can be PCI or USB based on device type field.
|
||||||
*
|
*
|
||||||
* @param dSEDbytes byte array holding the DeviceSecurityEventData.
|
* @param dsedDeviceContextBytes 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) {
|
public void instantiateDeviceContext(final byte[] dsedDeviceContextBytes) {
|
||||||
|
|
||||||
int deviceContextLength = dSEDbytes.length - startByte;
|
if (deviceType == DEVICE_TYPE_NONE) {
|
||||||
|
deviceContextInfo = "\n No Device Context (indicated by device type value of 0";
|
||||||
// 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) {
|
else if (deviceType == DEVICE_TYPE_PCI) {
|
||||||
DeviceSecurityEventDataPciContext dSEDpciContext
|
dsedDevContext
|
||||||
= new DeviceSecurityEventDataPciContext(deviceContextBytes);
|
= new DeviceSecurityEventDataPciContext(dsedDeviceContextBytes);
|
||||||
deviceContextInfo = dSEDpciContext.toString();
|
deviceContextInfo = dsedDevContext.toString();
|
||||||
|
}
|
||||||
|
else if (deviceType == DEVICE_TYPE_USB) {
|
||||||
|
// dsedDevContext
|
||||||
|
// = new DeviceSecurityEventDataUsbContext(dsedDeviceContextBytes);
|
||||||
|
// deviceContextInfo = dsedDevContext.toString();
|
||||||
|
deviceContextInfo = " Device Type: USB - To be implemented";
|
||||||
}
|
}
|
||||||
//else if (deviceType == 2) {
|
|
||||||
//DeviceSecurityEventDataUsbContext dSEDusbContext
|
|
||||||
// = new DeviceSecurityEventDataUsbContext(deviceContextBytes);
|
|
||||||
//deviceContextInfo = dSEDusbContext.toString();
|
|
||||||
//deviceContextInfo = "Device type is USB - to be implemented in future";
|
|
||||||
//}
|
|
||||||
else {
|
else {
|
||||||
deviceContextInfo = " Unknown device type; cannot process device context";
|
deviceContextInfo = " Unknown device type; cannot process device context";
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
package hirs.utils.tpm.eventlog.events;
|
package hirs.utils.tpm.eventlog.events;
|
||||||
|
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
import java.io.UnsupportedEncodingException;
|
import java.io.UnsupportedEncodingException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -24,15 +26,23 @@ public class DeviceSecurityEventData extends DeviceSecurityEvent {
|
|||||||
/**
|
/**
|
||||||
* DeviceSecurityEventData Constructor.
|
* DeviceSecurityEventData Constructor.
|
||||||
*
|
*
|
||||||
* @param dSEDbytes byte array holding the DeviceSecurityEventData.
|
* @param dsedBytes byte array holding the DeviceSecurityEventData.
|
||||||
*/
|
*/
|
||||||
public DeviceSecurityEventData(final byte[] dSEDbytes) throws UnsupportedEncodingException {
|
public DeviceSecurityEventData(final byte[] dsedBytes) {
|
||||||
dsedHeader = new DeviceSecurityEventDataHeader(dSEDbytes);
|
dsedHeader = new DeviceSecurityEventDataHeader(dsedBytes);
|
||||||
parseDeviceContext(dSEDbytes, dsedHeader.getDSEDheaderByteSize(), dsedHeader.getDeviceType());
|
setDeviceType(dsedHeader.getDeviceType());
|
||||||
|
int dsedHeaderLength = dsedHeader.getDsedHeaderLength();
|
||||||
|
|
||||||
|
int dsedDevContextLength = dsedBytes.length - dsedHeaderLength;
|
||||||
|
byte[] dsedDevContextBytes = new byte[dsedDevContextLength];
|
||||||
|
System.arraycopy(dsedBytes, dsedHeaderLength, dsedDevContextBytes, 0,
|
||||||
|
dsedDevContextLength);
|
||||||
|
|
||||||
|
instantiateDeviceContext(dsedDevContextBytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a human readable description of the data within this structure.
|
* Returns a human-readable description of the data within this structure.
|
||||||
*
|
*
|
||||||
* @return a description of this structure.
|
* @return a description of this structure.
|
||||||
*/
|
*/
|
||||||
|
@ -2,7 +2,12 @@ package hirs.utils.tpm.eventlog.events;
|
|||||||
|
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
|
|
||||||
// TODO Placeholder class to be implemented upon getting test pattern
|
import java.io.IOException;
|
||||||
|
import java.io.UnsupportedEncodingException;
|
||||||
|
|
||||||
|
import static hirs.utils.tpm.eventlog.events.DeviceSecurityEventDataHeader2.SUBHEADERTYPE_CERT_CHAIN;
|
||||||
|
import static hirs.utils.tpm.eventlog.events.DeviceSecurityEventDataHeader2.SUBHEADERTYPE_MEAS_BLOCK;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class to process DEVICE_SECURITY_EVENT_DATA2.
|
* Class to process DEVICE_SECURITY_EVENT_DATA2.
|
||||||
* Parses event data per PFP v1.06 Rev52 Table 26.
|
* Parses event data per PFP v1.06 Rev52 Table 26.
|
||||||
@ -22,25 +27,70 @@ public class DeviceSecurityEventData2 extends DeviceSecurityEvent {
|
|||||||
@Getter
|
@Getter
|
||||||
private DeviceSecurityEventDataHeader2 dsedHeader2 = null;
|
private DeviceSecurityEventDataHeader2 dsedHeader2 = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* DeviceSecurityEventDataSubHeader Object.
|
||||||
|
*/
|
||||||
|
@Getter
|
||||||
|
private DeviceSecurityEventDataSubHeader dsedSubHeader = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Human readable description of the data within the
|
||||||
|
* DEVICE_SECURITY_EVENT_DATA_SUB_HEADER. SUB_HEADER can be either
|
||||||
|
* DEVICE_SECURITY_EVENT_DATA_SUB_HEADER_SPDM_MEASUREMENT_BLOCK or
|
||||||
|
* DEVICE_SECURITY_EVENT_DATA_SUB_HEADER_SPDM_CERT_CHAIN
|
||||||
|
*/
|
||||||
|
@Getter
|
||||||
|
String subHeaderInfo = "";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* DeviceSecurityEventData2 Constructor.
|
* DeviceSecurityEventData2 Constructor.
|
||||||
*
|
*
|
||||||
* @param dSEDbytes byte array holding the DeviceSecurityEventData2.
|
* @param dsedBytes byte array holding the DeviceSecurityEventData2.
|
||||||
*/
|
*/
|
||||||
public DeviceSecurityEventData2(final byte[] dSEDbytes) {
|
public DeviceSecurityEventData2(final byte[] dsedBytes) {
|
||||||
|
|
||||||
dsedHeader2 = new DeviceSecurityEventDataHeader2(dSEDbytes);
|
dsedHeader2 = new DeviceSecurityEventDataHeader2(dsedBytes);
|
||||||
// get subheader
|
setDeviceType(dsedHeader2.getDeviceType());
|
||||||
parseDeviceContext(dSEDbytes, dsedHeader2.getDSEDheaderByteSize(), dsedHeader2.getDeviceType());
|
int dsedHeaderLength = dsedHeader2.getDsedHeaderLength();
|
||||||
|
int subHeaderType = dsedHeader2.getSubHeaderType();
|
||||||
|
int subHeaderLength = dsedHeader2.getSubHeaderLength();
|
||||||
|
|
||||||
|
subHeaderInfo = "\nSub header type: " + subHeaderType;
|
||||||
|
|
||||||
|
byte[] dsedSubHeaderBytes = new byte[subHeaderLength];
|
||||||
|
System.arraycopy(dsedBytes, dsedHeaderLength, dsedSubHeaderBytes, 0, subHeaderLength);
|
||||||
|
|
||||||
|
if (subHeaderType == SUBHEADERTYPE_MEAS_BLOCK) {
|
||||||
|
dsedSubHeader = new DeviceSecurityEventDataSubHeaderSpdmMeasurementBlock(dsedSubHeaderBytes);
|
||||||
|
subHeaderInfo += dsedSubHeader.toString();
|
||||||
|
}
|
||||||
|
else if (subHeaderType == SUBHEADERTYPE_CERT_CHAIN) {
|
||||||
|
// dsedSubHeader = new DeviceSecurityEventDataSubHeaderCertChain();
|
||||||
|
subHeaderInfo += " Cert chain to be implemented ";
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
subHeaderInfo += "Sub header type unknown";
|
||||||
|
}
|
||||||
|
|
||||||
|
int dsedDevContextStartByte = dsedHeaderLength + subHeaderLength;
|
||||||
|
int dsedDevContextLength = dsedBytes.length - dsedDevContextStartByte;
|
||||||
|
byte[] dsedDevContextBytes = new byte[dsedDevContextLength];
|
||||||
|
System.arraycopy(dsedBytes, dsedDevContextStartByte, dsedDevContextBytes, 0,
|
||||||
|
dsedDevContextLength);
|
||||||
|
|
||||||
|
instantiateDeviceContext(dsedDevContextBytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a human readable description of the data within this structure.
|
* Returns a human-readable description of the data within this structure.
|
||||||
*
|
*
|
||||||
* @return a description of this structure.
|
* @return a description of this structure.
|
||||||
*/
|
*/
|
||||||
public String toString() {
|
public String toString() {
|
||||||
String dsedInfo = "";
|
String dsedInfo = "";
|
||||||
|
dsedInfo += dsedHeader2.toString();
|
||||||
|
dsedInfo += dsedSubHeader.toString();
|
||||||
|
dsedInfo += getDeviceContextInfo();
|
||||||
return dsedInfo;
|
return dsedInfo;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -31,17 +31,17 @@ public abstract class DeviceSecurityEventDataDeviceContext {
|
|||||||
/**
|
/**
|
||||||
* DeviceSecurityEventDataDeviceContext Constructor.
|
* DeviceSecurityEventDataDeviceContext Constructor.
|
||||||
*
|
*
|
||||||
* @param dSEDdeviceContextBytes byte array holding the DeviceSecurityEventData.
|
* @param dsedDeviceContextBytes byte array holding the DeviceSecurityEventData.
|
||||||
*/
|
*/
|
||||||
public DeviceSecurityEventDataDeviceContext(final byte[] dSEDdeviceContextBytes) {
|
public DeviceSecurityEventDataDeviceContext(final byte[] dsedDeviceContextBytes) {
|
||||||
|
|
||||||
byte[] pciVersionBytes = new byte[2];
|
byte[] versionBytes = new byte[2];
|
||||||
System.arraycopy(dSEDdeviceContextBytes, 0, pciVersionBytes, 0, 2);
|
System.arraycopy(dsedDeviceContextBytes, 0, versionBytes, 0, 2);
|
||||||
version = HexUtils.leReverseInt(pciVersionBytes);
|
version = HexUtils.leReverseInt(versionBytes);
|
||||||
|
|
||||||
byte[] pciLengthBytes = new byte[2];
|
byte[] lengthBytes = new byte[2];
|
||||||
System.arraycopy(dSEDdeviceContextBytes, 2, pciLengthBytes, 0, 2);
|
System.arraycopy(dsedDeviceContextBytes, 2, lengthBytes, 0, 2);
|
||||||
length = HexUtils.leReverseInt(pciLengthBytes);
|
length = HexUtils.leReverseInt(lengthBytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -52,8 +52,7 @@ public abstract class DeviceSecurityEventDataDeviceContext {
|
|||||||
public String toString() {
|
public String toString() {
|
||||||
String dSEDdeviceContextCommonInfo = "";
|
String dSEDdeviceContextCommonInfo = "";
|
||||||
|
|
||||||
dSEDdeviceContextCommonInfo += "\n DeviceSecurityEventData Device Info:";
|
dSEDdeviceContextCommonInfo += "\n DeviceSecurityEventData Device Context:";
|
||||||
dSEDdeviceContextCommonInfo += "\n Device Structure Version = " + version;
|
|
||||||
|
|
||||||
return dSEDdeviceContextCommonInfo;
|
return dSEDdeviceContextCommonInfo;
|
||||||
}
|
}
|
||||||
|
@ -6,6 +6,8 @@ import hirs.utils.tpm.eventlog.spdm.SpdmMeasurementBlock;
|
|||||||
import hirs.utils.tpm.eventlog.uefi.UefiConstants;
|
import hirs.utils.tpm.eventlog.uefi.UefiConstants;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
|
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
|
import java.io.IOException;
|
||||||
import java.io.UnsupportedEncodingException;
|
import java.io.UnsupportedEncodingException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -49,43 +51,46 @@ public class DeviceSecurityEventDataHeader extends DeviceSecurityEventHeader {
|
|||||||
/**
|
/**
|
||||||
* DeviceSecurityEventDataHeader Constructor.
|
* DeviceSecurityEventDataHeader Constructor.
|
||||||
*
|
*
|
||||||
* @param dSEDbytes byte array holding the DeviceSecurityEventData.
|
* @param dsedBytes byte array holding the DeviceSecurityEventData.
|
||||||
*/
|
*/
|
||||||
public DeviceSecurityEventDataHeader(final byte[] dSEDbytes) throws UnsupportedEncodingException {
|
public DeviceSecurityEventDataHeader(final byte[] dsedBytes) {
|
||||||
|
|
||||||
super(dSEDbytes);
|
super(dsedBytes);
|
||||||
|
|
||||||
byte[] lengthBytes = new byte[UefiConstants.SIZE_2];
|
byte[] lengthBytes = new byte[UefiConstants.SIZE_2];
|
||||||
System.arraycopy(dSEDbytes, 18, lengthBytes, 0,
|
System.arraycopy(dsedBytes, 18, lengthBytes, 0,
|
||||||
UefiConstants.SIZE_2);
|
UefiConstants.SIZE_2);
|
||||||
length = HexUtils.leReverseInt(lengthBytes);
|
length = HexUtils.leReverseInt(lengthBytes);
|
||||||
|
|
||||||
byte[] spdmHashAlgoBytes = new byte[UefiConstants.SIZE_4];
|
byte[] spdmHashAlgoBytes = new byte[UefiConstants.SIZE_4];
|
||||||
System.arraycopy(dSEDbytes, UefiConstants.OFFSET_20, spdmHashAlgoBytes, 0,
|
System.arraycopy(dsedBytes, UefiConstants.OFFSET_20, spdmHashAlgoBytes, 0,
|
||||||
UefiConstants.SIZE_4);
|
UefiConstants.SIZE_4);
|
||||||
spdmHashAlgo = HexUtils.leReverseInt(spdmHashAlgoBytes);
|
spdmHashAlgo = HexUtils.leReverseInt(spdmHashAlgoBytes);
|
||||||
|
|
||||||
extractDeviceType(dSEDbytes, 24);
|
extractDeviceType(dsedBytes, 24);
|
||||||
|
|
||||||
// get the size of the SPDM Measurement Block
|
// get the size of the SPDM Measurement Block
|
||||||
byte[] sizeOfSpdmMeasBlockBytes = new byte[UefiConstants.SIZE_2];
|
byte[] sizeOfSpdmMeasBlockBytes = new byte[UefiConstants.SIZE_2];
|
||||||
System.arraycopy(dSEDbytes, 30, sizeOfSpdmMeasBlockBytes, 0,
|
System.arraycopy(dsedBytes, 30, sizeOfSpdmMeasBlockBytes, 0,
|
||||||
UefiConstants.SIZE_2);
|
UefiConstants.SIZE_2);
|
||||||
int sizeOfSpdmMeas = HexUtils.leReverseInt(sizeOfSpdmMeasBlockBytes);
|
int sizeOfSpdmMeas = HexUtils.leReverseInt(sizeOfSpdmMeasBlockBytes);
|
||||||
int sizeOfSpdmMeasBlock = sizeOfSpdmMeas + 4; // header is 4 bytes
|
int sizeOfSpdmMeasBlock = sizeOfSpdmMeas + 4; // header is 4 bytes
|
||||||
|
|
||||||
// extract the bytes from the SPDM Measurement Block
|
// extract the bytes that comprise the SPDM Measurement Block
|
||||||
byte[] spdmMeasBlockBytes = new byte[sizeOfSpdmMeasBlock];
|
byte[] spdmMeasBlockBytes = new byte[sizeOfSpdmMeasBlock];
|
||||||
System.arraycopy(dSEDbytes, 28, spdmMeasBlockBytes, 0,
|
System.arraycopy(dsedBytes, 28, spdmMeasBlockBytes, 0,
|
||||||
sizeOfSpdmMeasBlock);
|
sizeOfSpdmMeasBlock);
|
||||||
spdmMeasurementBlock = new SpdmMeasurementBlock(spdmMeasBlockBytes);
|
|
||||||
|
ByteArrayInputStream spdmMeasurementBlockData =
|
||||||
|
new ByteArrayInputStream(spdmMeasBlockBytes);
|
||||||
|
spdmMeasurementBlock = new SpdmMeasurementBlock(spdmMeasurementBlockData);
|
||||||
|
|
||||||
int devPathLenStartByte = 28 + sizeOfSpdmMeasBlock;
|
int devPathLenStartByte = 28 + sizeOfSpdmMeasBlock;
|
||||||
extractDevicePathAndFinalSize(dSEDbytes, devPathLenStartByte);
|
extractDevicePathAndFinalSize(dsedBytes, devPathLenStartByte);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a human readable description of the data within this structure.
|
* Returns a human-readable description of the data within this structure.
|
||||||
*
|
*
|
||||||
* @return a description of this structure.
|
* @return a description of this structure.
|
||||||
*/
|
*/
|
||||||
|
@ -1,22 +1,161 @@
|
|||||||
package hirs.utils.tpm.eventlog.events;
|
package hirs.utils.tpm.eventlog.events;
|
||||||
|
|
||||||
import hirs.utils.tpm.eventlog.spdm.SpdmHa;
|
import hirs.utils.HexUtils;
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
// Placeholder for Header2 data structure.
|
import java.io.UnsupportedEncodingException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class to process the DEVICE_SECURITY_EVENT_DATA_HEADER2.
|
||||||
|
* DEVICE_SECURITY_EVENT_DATA_HEADER2 contains the measurement(s) and hash algorithm identifier
|
||||||
|
* returned by the SPDM "GET_MEASUREMENTS" function.
|
||||||
|
*
|
||||||
|
* HEADERS defined by PFP v1.06 Rev 52:
|
||||||
|
* <p>
|
||||||
|
* typedef struct tdDEVICE_SECURITY_EVENT_DATA_HEADER2 {
|
||||||
|
* UINT8 Signature[16];
|
||||||
|
* UINT16 Version;
|
||||||
|
* UINT8 AuthState;
|
||||||
|
* UINT8 Reserved
|
||||||
|
* UINT32 Length;
|
||||||
|
* UINT32 DeviceType;
|
||||||
|
* UINT32 SubHeaderType;
|
||||||
|
* UINT32 SubHeaderLength;
|
||||||
|
* UINT64 SubHeaderUID;
|
||||||
|
* UINT64 DevicePathLength;
|
||||||
|
* UNIT8 DevicePath[DevicePathLength]
|
||||||
|
* } DEVICE_SECURITY_EVENT_DATA_HEADER2;
|
||||||
|
* <p>
|
||||||
|
*/
|
||||||
public class DeviceSecurityEventDataHeader2 extends DeviceSecurityEventHeader {
|
public class DeviceSecurityEventDataHeader2 extends DeviceSecurityEventHeader {
|
||||||
|
|
||||||
public DeviceSecurityEventDataHeader2(final byte[] dSEDbytes) {
|
/**
|
||||||
|
* Event auth state
|
||||||
|
*/
|
||||||
|
@Getter
|
||||||
|
private int authState = 0;
|
||||||
|
/**
|
||||||
|
* Event data length.
|
||||||
|
*/
|
||||||
|
@Getter
|
||||||
|
private int length = 0;
|
||||||
|
/**
|
||||||
|
* Event sub headerType
|
||||||
|
*/
|
||||||
|
@Getter
|
||||||
|
private int subHeaderType = 0;
|
||||||
|
/**
|
||||||
|
* Event sub header length.
|
||||||
|
*/
|
||||||
|
@Getter
|
||||||
|
private int subHeaderLength = 0;
|
||||||
|
/**
|
||||||
|
* Event sub header UID.
|
||||||
|
*/
|
||||||
|
@Getter
|
||||||
|
private String subHeaderUid = "";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Auth state - success
|
||||||
|
*/
|
||||||
|
public static final int AUTH_SUCCESS = 0;
|
||||||
|
/**
|
||||||
|
* Auth state - digital signature of the data is valid, but the public key certificate chain is not
|
||||||
|
* validated with the entry in in the UEFI device signature variable
|
||||||
|
*/
|
||||||
|
public static final int AUTH_NO_AUTHORITY = 1;
|
||||||
|
/**
|
||||||
|
* Auth state - digital signature of the measurement data is valid, but the reported device capabilities,
|
||||||
|
* negotiated parameters or certificate chains were not validated by a transcript.
|
||||||
|
*/
|
||||||
|
public static final int AUTH_NO_BINDING = 2;
|
||||||
|
/**
|
||||||
|
* Auth state - data has no digital signature
|
||||||
|
*/
|
||||||
|
public static final int AUTH_FAIL_NO_SIG = 3;
|
||||||
|
/**
|
||||||
|
* Auth state - data is invalid
|
||||||
|
*/
|
||||||
|
public static final int AUTH_FAIL_INVALID = 4;
|
||||||
|
/**
|
||||||
|
* Auth state - device is not an SPDM-capable device
|
||||||
|
*/
|
||||||
|
public static final int AUTH_NO_SPDM = 0xFF;
|
||||||
|
/**
|
||||||
|
* Sub header type - SPDM measurement block
|
||||||
|
*/
|
||||||
|
public static final int SUBHEADERTYPE_MEAS_BLOCK = 0;
|
||||||
|
/**
|
||||||
|
* Sub header type - SPDM cert chain
|
||||||
|
*/
|
||||||
|
public static final int SUBHEADERTYPE_CERT_CHAIN = 1;
|
||||||
|
|
||||||
|
|
||||||
|
public DeviceSecurityEventDataHeader2(final byte[] dsedBytes) {
|
||||||
|
|
||||||
|
super(dsedBytes);
|
||||||
|
|
||||||
|
byte[] authStateBytes = new byte[1];
|
||||||
|
System.arraycopy(dsedBytes, 18, authStateBytes, 0, 1);
|
||||||
|
authState = HexUtils.leReverseInt(authStateBytes);
|
||||||
|
|
||||||
|
// byte[] reserved[Bytes]: 1 byte
|
||||||
|
|
||||||
|
byte[] lengthBytes = new byte[4];
|
||||||
|
System.arraycopy(dsedBytes, 20, lengthBytes, 0, 4);
|
||||||
|
length = HexUtils.leReverseInt(lengthBytes);
|
||||||
|
|
||||||
|
extractDeviceType(dsedBytes, 24);
|
||||||
|
|
||||||
|
byte[] subHeaderTypeBytes = new byte[4];
|
||||||
|
System.arraycopy(dsedBytes, 28, subHeaderTypeBytes, 0, 4);
|
||||||
|
subHeaderType = HexUtils.leReverseInt(subHeaderTypeBytes);
|
||||||
|
|
||||||
|
byte[] subHeaderLengthBytes = new byte[4];
|
||||||
|
System.arraycopy(dsedBytes, 32, subHeaderLengthBytes, 0, 4);
|
||||||
|
subHeaderLength = HexUtils.leReverseInt(subHeaderLengthBytes);
|
||||||
|
|
||||||
|
byte[] subHeaderUidBytes = new byte[8];
|
||||||
|
System.arraycopy(dsedBytes, 36, subHeaderUidBytes, 0, 8);
|
||||||
|
subHeaderUidBytes = HexUtils.leReverseByte(subHeaderUidBytes);
|
||||||
|
subHeaderUid = HexUtils.byteArrayToHexString(subHeaderUidBytes);
|
||||||
|
|
||||||
|
int devPathLenStartByte = 44;
|
||||||
|
extractDevicePathAndFinalSize(dsedBytes, devPathLenStartByte);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a human readable description of the data within this structure.
|
* Returns a human-readable description of the data within this structure.
|
||||||
*
|
*
|
||||||
* @return a description of this structure.
|
* @return a description of this structure.
|
||||||
*/
|
*/
|
||||||
public String toString() {
|
public String toString() {
|
||||||
String dsedHeader2Info = "";
|
String dsedHeader2Info = "";
|
||||||
|
|
||||||
|
dsedHeader2Info += super.toString();
|
||||||
|
dsedHeader2Info += "\n AuthState: " + getAuthStateString();
|
||||||
|
dsedHeader2Info += "\n Sub header UID: " + subHeaderUid;
|
||||||
|
|
||||||
return dsedHeader2Info;
|
return dsedHeader2Info;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getAuthStateString() {
|
||||||
|
|
||||||
|
switch (authState) {
|
||||||
|
case AUTH_SUCCESS:
|
||||||
|
return ("AUTH_SUCCESS");
|
||||||
|
case AUTH_NO_AUTHORITY:
|
||||||
|
return ("AUTH_NO_AUTHORITY");
|
||||||
|
case AUTH_NO_BINDING:
|
||||||
|
return ("AUTH_NO_BINDING");
|
||||||
|
case AUTH_FAIL_NO_SIG:
|
||||||
|
return ("AUTH_FAIL_NO_SIG");
|
||||||
|
case AUTH_FAIL_INVALID:
|
||||||
|
return ("AUTH_FAIL_INVALID");
|
||||||
|
case AUTH_NO_SPDM:
|
||||||
|
return ("AUTH_NO_SPDM");
|
||||||
|
default:
|
||||||
|
return ("Auth State unknown");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,20 @@
|
|||||||
|
package hirs.utils.tpm.eventlog.events;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class to process the DEVICE_SECURITY_EVENT_DATA_SUB_HEADER event per PFP.
|
||||||
|
*
|
||||||
|
* <p>
|
||||||
|
* typedef union tdDEVICE_SECURITY_EVENT_DATA_SUB_HEADER {
|
||||||
|
* DEVICE_SECURITY_EVENT_DATA_SUB_HEADER_SPDM_MEASUREMENT_BLOCK SpdmMeasurementBlock;
|
||||||
|
* DEVICE_SECURITY_EVENT_DATA_SUB_HEADER_SPDM_CERT_CHAIN SpdmCertChain;
|
||||||
|
* DEVICE_SECURITY_EVENT_DATA_SUB_HEADER_OEM_MEASUREMENT OemMeasurement;
|
||||||
|
* } DEVICE_SECURITY_EVENT_DATA_SUB_HEADER;
|
||||||
|
* <p>
|
||||||
|
*/
|
||||||
|
public abstract class DeviceSecurityEventDataSubHeader {
|
||||||
|
|
||||||
|
public DeviceSecurityEventDataSubHeader() {
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,111 @@
|
|||||||
|
package hirs.utils.tpm.eventlog.events;
|
||||||
|
|
||||||
|
import hirs.utils.HexUtils;
|
||||||
|
import hirs.utils.tpm.eventlog.spdm.SpdmHa;
|
||||||
|
import hirs.utils.tpm.eventlog.spdm.SpdmMeasurementBlock;
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class to process the DEVICE_SECURITY_EVENT_DATA_SUB_HEADER_SPDM_MEASUREMENT_BLOCK event per PFP.
|
||||||
|
*
|
||||||
|
* <p>
|
||||||
|
* typedef union tdDEVICE_SECURITY_EVENT_DATA_SUB_HEADER_SPDM_MEASUREMENT_BLOCK {
|
||||||
|
* UINT16 SpdmVersion;
|
||||||
|
* UINT8 SpdmMeasurementBlockCount;
|
||||||
|
* UINT8 Reserved;
|
||||||
|
* UINT32 SpdmMeasurementHashAlgo;
|
||||||
|
* SPDM_MEASUREMENT_BLOCK SpdmMeasurementBlock[SpdmMeasurementBlockCount];
|
||||||
|
* } DEVICE_SECURITY_EVENT_DATA_SUB_HEADER_SPDM_MEASUREMENT_BLOCK;
|
||||||
|
* <p>
|
||||||
|
*/
|
||||||
|
public class DeviceSecurityEventDataSubHeaderSpdmMeasurementBlock extends DeviceSecurityEventDataSubHeader {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SPDM version.
|
||||||
|
*/
|
||||||
|
@Getter
|
||||||
|
private int spdmVersion = 0;
|
||||||
|
/**
|
||||||
|
* SPDM measurement block count.
|
||||||
|
*/
|
||||||
|
@Getter
|
||||||
|
private int spdmMeasurementBlockCount = 0;
|
||||||
|
/**
|
||||||
|
* SPDM measurement hash algorithm.
|
||||||
|
*/
|
||||||
|
@Getter
|
||||||
|
private int spdmMeasurementHashAlgo = -1;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* List of SPDM Measurement Blocks.
|
||||||
|
*/
|
||||||
|
private List<SpdmMeasurementBlock> spdmMeasurementBlockList;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* DeviceSecurityEventDataHeader Constructor.
|
||||||
|
*
|
||||||
|
* @param dsedSubHBytes byte array holding the DeviceSecurityEventDataSubHeaderSpdmMeasurementBlock.
|
||||||
|
*/
|
||||||
|
public DeviceSecurityEventDataSubHeaderSpdmMeasurementBlock(final byte[] dsedSubHBytes) {
|
||||||
|
|
||||||
|
spdmMeasurementBlockList = new ArrayList<>();
|
||||||
|
|
||||||
|
byte[] spdmVersionBytes = new byte[2];
|
||||||
|
System.arraycopy(dsedSubHBytes, 0, spdmVersionBytes, 0, 2);
|
||||||
|
spdmVersion = HexUtils.leReverseInt(spdmVersionBytes);
|
||||||
|
|
||||||
|
byte[] spdmMeasurementBlockCountBytes = new byte[1];
|
||||||
|
System.arraycopy(dsedSubHBytes, 2, spdmMeasurementBlockCountBytes, 0, 1);
|
||||||
|
spdmMeasurementBlockCount = HexUtils.leReverseInt(spdmMeasurementBlockCountBytes);
|
||||||
|
|
||||||
|
// byte[] reserved[Bytes]: 1 byte
|
||||||
|
|
||||||
|
byte[] spdmMeasurementHashAlgoBytes = new byte[4];
|
||||||
|
System.arraycopy(dsedSubHBytes, 4, spdmMeasurementHashAlgoBytes, 0, 4);
|
||||||
|
spdmMeasurementHashAlgo = HexUtils.leReverseInt(spdmMeasurementHashAlgoBytes);
|
||||||
|
|
||||||
|
// get the size of the SPDM Measurement Block List
|
||||||
|
int spdmMeasurementBlockListSize = dsedSubHBytes.length - 8;
|
||||||
|
|
||||||
|
// extract the bytes that comprise the SPDM Measurement Block List
|
||||||
|
byte[] spdmMeasurementBlockListBytes = new byte[spdmMeasurementBlockListSize];
|
||||||
|
System.arraycopy(dsedSubHBytes, 8, spdmMeasurementBlockListBytes, 0,
|
||||||
|
spdmMeasurementBlockListSize);
|
||||||
|
|
||||||
|
ByteArrayInputStream spdmMeasurementBlockListData =
|
||||||
|
new ByteArrayInputStream(spdmMeasurementBlockListBytes);
|
||||||
|
while (spdmMeasurementBlockListData.available() > 0) {
|
||||||
|
SpdmMeasurementBlock spdmMeasurementBlock;
|
||||||
|
spdmMeasurementBlock = new SpdmMeasurementBlock(spdmMeasurementBlockListData);
|
||||||
|
spdmMeasurementBlockList.add(spdmMeasurementBlock);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a human-readable description of the data within this structure.
|
||||||
|
*
|
||||||
|
* @return a description of this structure.
|
||||||
|
*/
|
||||||
|
public String toString() {
|
||||||
|
String dsedSubHeaderInfo = "";
|
||||||
|
dsedSubHeaderInfo += "\n SPDM Version: " + spdmVersion;
|
||||||
|
String spdmHashAlgoStr = SpdmHa.tcgAlgIdToString(spdmMeasurementHashAlgo);
|
||||||
|
dsedSubHeaderInfo += "\n SPDM Hash Algorithm = " + spdmHashAlgoStr;
|
||||||
|
|
||||||
|
// SPDM Measurement Block List output
|
||||||
|
dsedSubHeaderInfo += "\n Number of SPDM Measurement Blocks = " + spdmMeasurementBlockList.size();
|
||||||
|
int spdmMeasBlockCnt = 1;
|
||||||
|
for (SpdmMeasurementBlock spdmMeasBlock : spdmMeasurementBlockList) {
|
||||||
|
dsedSubHeaderInfo += "\n SPDM Measurement Block # " + spdmMeasBlockCnt++ + " of " +
|
||||||
|
spdmMeasurementBlockList.size();
|
||||||
|
dsedSubHeaderInfo += spdmMeasBlock.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
return dsedSubHeaderInfo;
|
||||||
|
}
|
||||||
|
}
|
@ -56,7 +56,8 @@ public abstract class DeviceSecurityEventHeader {
|
|||||||
* Contains the size (in bytes) of the header.
|
* Contains the size (in bytes) of the header.
|
||||||
*/
|
*/
|
||||||
@Getter
|
@Getter
|
||||||
private Integer dSEDheaderByteSize = 0;
|
private Integer dsedHeaderLength = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Signature (text) data.
|
* Signature (text) data.
|
||||||
*/
|
*/
|
||||||
@ -118,8 +119,8 @@ public abstract class DeviceSecurityEventHeader {
|
|||||||
|
|
||||||
byte[] signatureBytes = new byte[UefiConstants.SIZE_16];
|
byte[] signatureBytes = new byte[UefiConstants.SIZE_16];
|
||||||
System.arraycopy(dSEDbytes, 0, signatureBytes, 0, UefiConstants.SIZE_16);
|
System.arraycopy(dSEDbytes, 0, signatureBytes, 0, UefiConstants.SIZE_16);
|
||||||
signature = new String(signatureBytes, StandardCharsets.UTF_8)
|
signature = new String(signatureBytes, StandardCharsets.UTF_8);
|
||||||
.substring(0, UefiConstants.SIZE_15);
|
signature = signature.replaceAll("[^\\P{C}\t\r\n]", ""); // remove null characters
|
||||||
|
|
||||||
byte[] versionBytes = new byte[UefiConstants.SIZE_2];
|
byte[] versionBytes = new byte[UefiConstants.SIZE_2];
|
||||||
System.arraycopy(dSEDbytes, UefiConstants.OFFSET_16, versionBytes, 0,
|
System.arraycopy(dSEDbytes, UefiConstants.OFFSET_16, versionBytes, 0,
|
||||||
@ -131,14 +132,14 @@ public abstract class DeviceSecurityEventHeader {
|
|||||||
/**
|
/**
|
||||||
* Parse the device type from the Device Security Event Data Header/Header2.
|
* Parse the device type from the Device Security Event Data Header/Header2.
|
||||||
*
|
*
|
||||||
* @param dSEDbytes byte array holding the DeviceSecurityEventData/Data2.
|
* @param dsedBytes byte array holding the DeviceSecurityEventData/Data2.
|
||||||
* @param startByte starting byte of device type (depends on header fields before it).
|
* @param startByte starting byte of device type (depends on header fields before it).
|
||||||
*/
|
*/
|
||||||
public void extractDeviceType(final byte[] dSEDbytes, int startByte) {
|
public void extractDeviceType(final byte[] dsedBytes, int startByte) {
|
||||||
|
|
||||||
// get the device type ID
|
// get the device type ID
|
||||||
byte[] deviceTypeBytes = new byte[UefiConstants.SIZE_4];
|
byte[] deviceTypeBytes = new byte[UefiConstants.SIZE_4];
|
||||||
System.arraycopy(dSEDbytes, startByte, deviceTypeBytes, 0,
|
System.arraycopy(dsedBytes, startByte, deviceTypeBytes, 0,
|
||||||
UefiConstants.SIZE_4);
|
UefiConstants.SIZE_4);
|
||||||
deviceType = HexUtils.leReverseInt(deviceTypeBytes);
|
deviceType = HexUtils.leReverseInt(deviceTypeBytes);
|
||||||
}
|
}
|
||||||
@ -147,15 +148,14 @@ public abstract class DeviceSecurityEventHeader {
|
|||||||
* Parse the device path from the Device Security Event Data Header/Header2.
|
* Parse the device path from the Device Security Event Data Header/Header2.
|
||||||
* Also, determine final length of header (will be used to extract the next data structure).
|
* Also, determine final length of header (will be used to extract the next data structure).
|
||||||
*
|
*
|
||||||
* @param dSEDbytes byte array holding the DeviceSecurityEventData/Data2.
|
* @param dsedBytes byte array holding the DeviceSecurityEventData/Data2.
|
||||||
* @param startByte starting byte of device path (depends on header fields before it).
|
* @param startByte starting byte of device path (depends on header fields before it).
|
||||||
*/
|
*/
|
||||||
public void extractDevicePathAndFinalSize(final byte[] dSEDbytes, int startByte)
|
public void extractDevicePathAndFinalSize(final byte[] dsedBytes, int startByte) {
|
||||||
throws UnsupportedEncodingException {
|
|
||||||
|
|
||||||
// get the device path length
|
// get the device path length
|
||||||
byte[] devicePathLengthBytes = new byte[UefiConstants.SIZE_8];
|
byte[] devicePathLengthBytes = new byte[UefiConstants.SIZE_8];
|
||||||
System.arraycopy(dSEDbytes, startByte, devicePathLengthBytes, 0,
|
System.arraycopy(dsedBytes, startByte, devicePathLengthBytes, 0,
|
||||||
UefiConstants.SIZE_8);
|
UefiConstants.SIZE_8);
|
||||||
int devicePathLength = HexUtils.leReverseInt(devicePathLengthBytes);
|
int devicePathLength = HexUtils.leReverseInt(devicePathLengthBytes);
|
||||||
|
|
||||||
@ -163,14 +163,19 @@ public abstract class DeviceSecurityEventHeader {
|
|||||||
if (devicePathLength != 0) {
|
if (devicePathLength != 0) {
|
||||||
startByte = startByte + UefiConstants.SIZE_8;
|
startByte = startByte + UefiConstants.SIZE_8;
|
||||||
byte[] devPathBytes = new byte[devicePathLength];
|
byte[] devPathBytes = new byte[devicePathLength];
|
||||||
System.arraycopy(dSEDbytes, startByte, devPathBytes,
|
System.arraycopy(dsedBytes, startByte, devPathBytes,
|
||||||
0, devicePathLength);
|
0, devicePathLength);
|
||||||
|
try {
|
||||||
devicePath = new UefiDevicePath(devPathBytes);
|
devicePath = new UefiDevicePath(devPathBytes);
|
||||||
devicePathValid = true;
|
devicePathValid = true;
|
||||||
}
|
}
|
||||||
|
catch (UnsupportedEncodingException e) {
|
||||||
|
devicePathValid = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// header total size
|
// header total size
|
||||||
dSEDheaderByteSize = startByte + devicePathLength;
|
dsedHeaderLength = startByte + devicePathLength;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -181,25 +186,20 @@ public abstract class DeviceSecurityEventHeader {
|
|||||||
* @return name of the device type
|
* @return name of the device type
|
||||||
*/
|
*/
|
||||||
public String deviceTypeToString(final int deviceTypeInt) {
|
public String deviceTypeToString(final int deviceTypeInt) {
|
||||||
String deviceTypeStr;
|
|
||||||
switch (deviceTypeInt) {
|
switch (deviceTypeInt) {
|
||||||
case DEVICE_TYPE_NONE:
|
case DEVICE_TYPE_NONE:
|
||||||
deviceTypeStr = "No device type";
|
return "No device type";
|
||||||
break;
|
|
||||||
case DEVICE_TYPE_PCI:
|
case DEVICE_TYPE_PCI:
|
||||||
deviceTypeStr = "PCI";
|
return "PCI";
|
||||||
break;
|
|
||||||
case DEVICE_TYPE_USB:
|
case DEVICE_TYPE_USB:
|
||||||
deviceTypeStr = "USB";
|
return "USB";
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
deviceTypeStr = "Unknown or invalid Device Type";
|
return "Unknown or invalid Device Type";
|
||||||
}
|
}
|
||||||
return deviceTypeStr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a human readable description of the data common to header structures.
|
* Returns a human-readable description of the data common to header structures.
|
||||||
*
|
*
|
||||||
* @return a description of this structure.
|
* @return a description of this structure.
|
||||||
*/
|
*/
|
||||||
|
@ -2,7 +2,9 @@ package hirs.utils.tpm.eventlog.events;
|
|||||||
|
|
||||||
import hirs.utils.HexUtils;
|
import hirs.utils.HexUtils;
|
||||||
import hirs.utils.tpm.eventlog.uefi.UefiConstants;
|
import hirs.utils.tpm.eventlog.uefi.UefiConstants;
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
import java.io.UnsupportedEncodingException;
|
import java.io.UnsupportedEncodingException;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
|
|
||||||
@ -31,10 +33,16 @@ import java.nio.charset.StandardCharsets;
|
|||||||
*/
|
*/
|
||||||
public class EvEfiSpdmDeviceSecurityEvent {
|
public class EvEfiSpdmDeviceSecurityEvent {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* DeviceSecurityEvent Object.
|
||||||
|
*/
|
||||||
|
private DeviceSecurityEvent dsed = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Signature (text) data.
|
* Signature (text) data.
|
||||||
*/
|
*/
|
||||||
private String signature = "";
|
private String signature = "";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Human readable description of the data within this DEVICE_SECURITY_EVENT_DATA/..DATA2 event.
|
* Human readable description of the data within this DEVICE_SECURITY_EVENT_DATA/..DATA2 event.
|
||||||
*/
|
*/
|
||||||
@ -46,32 +54,43 @@ public class EvEfiSpdmDeviceSecurityEvent {
|
|||||||
* @param eventData byte array holding the event to process.
|
* @param eventData byte array holding the event to process.
|
||||||
* @throws java.io.UnsupportedEncodingException if input fails to parse.
|
* @throws java.io.UnsupportedEncodingException if input fails to parse.
|
||||||
*/
|
*/
|
||||||
public EvEfiSpdmDeviceSecurityEvent(final byte[] eventData) throws UnsupportedEncodingException {
|
public EvEfiSpdmDeviceSecurityEvent(final byte[] eventData) {
|
||||||
|
|
||||||
byte[] signatureBytes = new byte[UefiConstants.SIZE_15];
|
byte[] signatureBytes = new byte[UefiConstants.SIZE_16];
|
||||||
System.arraycopy(eventData, 0, signatureBytes, 0, UefiConstants.SIZE_15);
|
System.arraycopy(eventData, 0, signatureBytes, 0, UefiConstants.SIZE_16);
|
||||||
signature = new String(signatureBytes, StandardCharsets.UTF_8);
|
signature = new String(signatureBytes, StandardCharsets.UTF_8);
|
||||||
signature = signature.replaceAll("[^\\P{C}\t\r\n]", ""); // remove null characters
|
signature = signature.replaceAll("[^\\P{C}\t\r\n]", ""); // remove null characters
|
||||||
|
|
||||||
if (signature.contains("SPDM Device Sec")) { // implies Device Security event
|
|
||||||
|
|
||||||
spdmInfo = " Signature = SPDM Device Sec";
|
|
||||||
|
|
||||||
byte[] versionBytes = new byte[UefiConstants.SIZE_2];
|
byte[] versionBytes = new byte[UefiConstants.SIZE_2];
|
||||||
System.arraycopy(eventData, UefiConstants.OFFSET_16, versionBytes, 0,
|
System.arraycopy(eventData, UefiConstants.OFFSET_16, versionBytes, 0,
|
||||||
UefiConstants.SIZE_2);
|
UefiConstants.SIZE_2);
|
||||||
String version = HexUtils.byteArrayToHexString(versionBytes);
|
String version = HexUtils.byteArrayToHexString(versionBytes);
|
||||||
|
if (version == "") {
|
||||||
if (version.equals("0100")) {
|
version = "version not readable";
|
||||||
DeviceSecurityEventData dSED = new DeviceSecurityEventData(eventData);
|
|
||||||
spdmInfo += dSED.toString();
|
|
||||||
}
|
}
|
||||||
else if (version.equals("0200")) {
|
|
||||||
DeviceSecurityEventData2 dSED2 = new DeviceSecurityEventData2(eventData);
|
if (signature.contains("SPDM Device Sec2")) {
|
||||||
spdmInfo += dSED2.toString();
|
|
||||||
|
spdmInfo = " Signature = SPDM Device Sec2";
|
||||||
|
|
||||||
|
if (version.equals("0200")) {
|
||||||
|
dsed = new DeviceSecurityEventData2(eventData);
|
||||||
|
spdmInfo += dsed.toString();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
spdmInfo += " Unknown version of DeviceSecurityEventData structure";
|
spdmInfo += " Incompatible version for DeviceSecurityEventData2: " + version;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (signature.contains("SPDM Device Sec")) { // implies Device Security event
|
||||||
|
|
||||||
|
spdmInfo = " Signature = SPDM Device Sec";
|
||||||
|
|
||||||
|
if (version.equals("0100")) {
|
||||||
|
dsed = new DeviceSecurityEventData(eventData);
|
||||||
|
spdmInfo += dsed.toString();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
spdmInfo += " Incompatible version for DeviceSecurityEventData: " + version;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -82,7 +101,7 @@ public class EvEfiSpdmDeviceSecurityEvent {
|
|||||||
/**
|
/**
|
||||||
* Returns a description of this event.
|
* Returns a description of this event.
|
||||||
*
|
*
|
||||||
* @return Human readable description of this event.
|
* @return Human-readable description of this event.
|
||||||
*/
|
*/
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return spdmInfo;
|
return spdmInfo;
|
||||||
|
@ -62,9 +62,11 @@ public class SpdmMeasurement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a human readable description of the data within this structure.
|
* Lookup for SPDM measurement value type
|
||||||
*
|
*
|
||||||
* @return a description of this structure..
|
* @param measValType the numerical representation of the measurement value type.
|
||||||
|
*
|
||||||
|
* @return a description of the measurement value type.
|
||||||
*/
|
*/
|
||||||
public String dmtfSpecMeasurementValueTypeToString(final int measValType) {
|
public String dmtfSpecMeasurementValueTypeToString(final int measValType) {
|
||||||
|
|
||||||
@ -92,7 +94,7 @@ public class SpdmMeasurement {
|
|||||||
measValTypeStr = "Mutable firmware's version number";
|
measValTypeStr = "Mutable firmware's version number";
|
||||||
break;
|
break;
|
||||||
case 7:
|
case 7:
|
||||||
measValTypeStr = "Mutable firmware's security verison number";
|
measValTypeStr = "Mutable firmware's security version number";
|
||||||
break;
|
break;
|
||||||
case 8:
|
case 8:
|
||||||
measValTypeStr = "Hash-extended measurement";
|
measValTypeStr = "Hash-extended measurement";
|
||||||
@ -109,6 +111,11 @@ public class SpdmMeasurement {
|
|||||||
return measValTypeStr;
|
return measValTypeStr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a human-readable description of the data within this structure.
|
||||||
|
*
|
||||||
|
* @return a description of this structure.
|
||||||
|
*/
|
||||||
public String toString() {
|
public String toString() {
|
||||||
String spdmMeasInfo = "";
|
String spdmMeasInfo = "";
|
||||||
|
|
||||||
|
@ -4,6 +4,14 @@ import hirs.utils.HexUtils;
|
|||||||
import hirs.utils.tpm.eventlog.uefi.UefiConstants;
|
import hirs.utils.tpm.eventlog.uefi.UefiConstants;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
|
|
||||||
|
import java.io.BufferedInputStream;
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
|
import java.io.FileInputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.UnsupportedEncodingException;
|
||||||
|
import java.security.MessageDigest;
|
||||||
|
import java.security.NoSuchAlgorithmException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class to process the SpdmMeasurementBlock.
|
* Class to process the SpdmMeasurementBlock.
|
||||||
* <p>
|
* <p>
|
||||||
@ -38,49 +46,58 @@ public class SpdmMeasurementBlock {
|
|||||||
* SPDM Measurement.
|
* SPDM Measurement.
|
||||||
*/
|
*/
|
||||||
private SpdmMeasurement spdmMeasurement;
|
private SpdmMeasurement spdmMeasurement;
|
||||||
|
/**
|
||||||
|
* Error reading SPDM Measurement Block.
|
||||||
|
*/
|
||||||
|
private boolean spdmMeasurementBlockReadError = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* SpdmMeasurementBlock Constructor.
|
* SpdmMeasurementBlock Constructor.
|
||||||
*
|
*
|
||||||
* @param spdmMeasBlockBytes byte array holding the SPDM Measurement Block bytes.
|
* @param spdmMeasBlocks byte array holding the SPDM Measurement Block bytes.
|
||||||
*/
|
*/
|
||||||
public SpdmMeasurementBlock(final byte[] spdmMeasBlockBytes) {
|
public SpdmMeasurementBlock(final ByteArrayInputStream spdmMeasBlocks) {
|
||||||
|
|
||||||
|
try {
|
||||||
byte[] indexBytes = new byte[1];
|
byte[] indexBytes = new byte[1];
|
||||||
System.arraycopy(spdmMeasBlockBytes, 0, indexBytes, 0,
|
spdmMeasBlocks.read(indexBytes);
|
||||||
1);
|
|
||||||
index = HexUtils.leReverseInt(indexBytes);
|
index = HexUtils.leReverseInt(indexBytes);
|
||||||
|
|
||||||
byte[] measurementSpecBytes = new byte[1];
|
byte[] measurementSpecBytes = new byte[1];
|
||||||
System.arraycopy(spdmMeasBlockBytes, 1, measurementSpecBytes, 0,
|
spdmMeasBlocks.read(measurementSpecBytes);
|
||||||
1);
|
|
||||||
measurementSpec = HexUtils.leReverseInt(measurementSpecBytes);
|
measurementSpec = HexUtils.leReverseInt(measurementSpecBytes);
|
||||||
|
|
||||||
// in future, can crosscheck this measurement size with the MeasurementSpec hash alg size
|
// in future, can crosscheck this measurement size with the MeasurementSpec hash alg size
|
||||||
byte[] measurementSizeBytes = new byte[2];
|
byte[] measurementSizeBytes = new byte[2];
|
||||||
System.arraycopy(spdmMeasBlockBytes, 2, measurementSizeBytes, 0,
|
spdmMeasBlocks.read(measurementSizeBytes);
|
||||||
2);
|
|
||||||
int measurementSize = HexUtils.leReverseInt(measurementSizeBytes);
|
int measurementSize = HexUtils.leReverseInt(measurementSizeBytes);
|
||||||
|
|
||||||
byte[] measurementBytes = new byte[measurementSize];
|
byte[] measurementBytes = new byte[measurementSize];
|
||||||
System.arraycopy(spdmMeasBlockBytes, 4, measurementBytes, 0,
|
spdmMeasBlocks.read(measurementBytes);
|
||||||
measurementSize);
|
|
||||||
spdmMeasurement = new SpdmMeasurement(measurementBytes);
|
spdmMeasurement = new SpdmMeasurement(measurementBytes);
|
||||||
|
} catch (IOException ioEx) {
|
||||||
|
spdmMeasurementBlockReadError = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a human readable description of the data within this structure.
|
* Returns a human-readable description of the data within this structure.
|
||||||
*
|
*
|
||||||
* @return a description of this structure..
|
* @return a description of this structure..
|
||||||
*/
|
*/
|
||||||
public String toString() {
|
public String toString() {
|
||||||
|
|
||||||
String spdmMeasBlockInfo = "";
|
String spdmMeasBlockInfo = "";
|
||||||
|
|
||||||
|
if(spdmMeasurementBlockReadError) {
|
||||||
|
spdmMeasBlockInfo += "\n Error reading SPDM Measurement Block";
|
||||||
|
}
|
||||||
|
else {
|
||||||
spdmMeasBlockInfo += "\n Index = " + index;
|
spdmMeasBlockInfo += "\n Index = " + index;
|
||||||
spdmMeasBlockInfo += "\n MeasurementSpec = " + measurementSpec;
|
spdmMeasBlockInfo += "\n MeasurementSpec = " + measurementSpec;
|
||||||
spdmMeasBlockInfo += spdmMeasurement.toString();
|
spdmMeasBlockInfo += spdmMeasurement.toString();
|
||||||
|
}
|
||||||
|
|
||||||
return spdmMeasBlockInfo;
|
return spdmMeasBlockInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -216,10 +216,11 @@ public class UefiVariable {
|
|||||||
case "KEK":
|
case "KEK":
|
||||||
case "db":
|
case "db":
|
||||||
case "dbx":
|
case "dbx":
|
||||||
|
break;
|
||||||
case "devdb": // SPDM_DEVICE_POLICY and SPDM_DEVICE_AUTHORITY
|
case "devdb": // SPDM_DEVICE_POLICY and SPDM_DEVICE_AUTHORITY
|
||||||
// (update when test patterns exist)
|
// (update when test patterns exist)
|
||||||
efiVariable.append(" EV_EFI_SPDM_DEVICE_POLICY and EV_EFI_SPDM_DEVICE_AUTHORITY: " +
|
efiVariable.append(" EV_EFI_SPDM_DEVICE_POLICY and EV_EFI_SPDM_DEVICE_AUTHORITY: " +
|
||||||
"To be processed once more test patterns exist\n");
|
"To be processed once more test patterns exist");
|
||||||
break;
|
break;
|
||||||
case "Boot00":
|
case "Boot00":
|
||||||
efiVariable.append(bootv.toString());
|
efiVariable.append(bootv.toString());
|
||||||
|
Loading…
Reference in New Issue
Block a user