implementing NvIndexInstance and supporting code

This commit is contained in:
iadgovuser58 2024-07-08 18:24:03 -04:00
parent 9d837f9b4d
commit 6b1731df08
8 changed files with 241 additions and 110 deletions

View File

@ -555,9 +555,7 @@ public class TpmPcrEvent {
case EvConstants.EV_EFI_HCRTM_EVENT:
break;
case EvConstants.EV_EFI_SPDM_FIRMWARE_BLOB:
EvEfiSpdmDeviceSecurityEvent tempp = new EvEfiSpdmDeviceSecurityEvent(content);
description += "Event Content:\n" + tempp.toString();
// description += "Event Content:\n" + new EvEfiSpdmDeviceSecurityEvent(content).toString();
description += "Event Content:\n" + new EvEfiSpdmDeviceSecurityEvent(content).toString();
break;
case EvConstants.EV_EFI_SPDM_FIRMWARE_CONFIG:
description += "Event Content:\n" + new EvEfiSpdmDeviceSecurityEvent(content).toString();

View File

@ -1,5 +1,6 @@
package hirs.utils.tpm.eventlog.events;
import hirs.utils.tpm.eventlog.spdm.SpdmMeasurementBlock;
import lombok.Getter;
import lombok.Setter;
@ -84,9 +85,14 @@ public abstract class DeviceSecurityEvent {
deviceContextInfo = "\n No Device Context (indicated by device type value of 0";
}
else if (deviceType == DEVICE_TYPE_PCI) {
dsedDevContext
= new DeviceSecurityEventDataPciContext(dsedDeviceContextBytes);
deviceContextInfo = dsedDevContext.toString();
try {
dsedDevContext
= new DeviceSecurityEventDataPciContext(dsedDeviceContextBytes);
deviceContextInfo = dsedDevContext.toString();
}
catch(NullPointerException e) {
deviceContextInfo = " Could not interpret Device Context info";
}
}
else if (deviceType == DEVICE_TYPE_USB) {
// dsedDevContext

View File

@ -23,22 +23,37 @@ public class DeviceSecurityEventData extends DeviceSecurityEvent {
@Getter
private DeviceSecurityEventDataHeader dsedHeader = null;
/**
* Human-readable description of the data within the
* DEVICE_SECURITY_EVENT_DATA_HEADER.
*/
@Getter
String headerInfo = "";
/**
* DeviceSecurityEventData Constructor.
*
* @param dsedBytes byte array holding the DeviceSecurityEventData.
*/
public DeviceSecurityEventData(final byte[] dsedBytes) {
dsedHeader = new DeviceSecurityEventDataHeader(dsedBytes);
setDeviceType(dsedHeader.getDeviceType());
int dsedHeaderLength = dsedHeader.getDsedHeaderLength();
int dsedDevContextLength = dsedBytes.length - dsedHeaderLength;
byte[] dsedDevContextBytes = new byte[dsedDevContextLength];
System.arraycopy(dsedBytes, dsedHeaderLength, dsedDevContextBytes, 0,
dsedDevContextLength);
try {
dsedHeader = new DeviceSecurityEventDataHeader(dsedBytes);
headerInfo = dsedHeader.toString();
instantiateDeviceContext(dsedDevContextBytes);
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);
}
catch(NullPointerException e) {
headerInfo = " Could not interpret Header info";
}
}
/**
@ -48,7 +63,7 @@ public class DeviceSecurityEventData extends DeviceSecurityEvent {
*/
public String toString() {
String dsedInfo = "";
dsedInfo += dsedHeader.toString();
dsedInfo += headerInfo;
dsedInfo += getDeviceContextInfo();
return dsedInfo;
}

View File

@ -34,7 +34,14 @@ public class DeviceSecurityEventData2 extends DeviceSecurityEvent {
private DeviceSecurityEventDataSubHeader dsedSubHeader = null;
/**
* Human readable description of the data within the
* Human-readable description of the data within the
* DEVICE_SECURITY_EVENT_DATA_HEADER2.
*/
@Getter
String headerInfo = "";
/**
* 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
@ -49,36 +56,48 @@ public class DeviceSecurityEventData2 extends DeviceSecurityEvent {
*/
public DeviceSecurityEventData2(final byte[] dsedBytes) {
dsedHeader2 = new DeviceSecurityEventDataHeader2(dsedBytes);
setDeviceType(dsedHeader2.getDeviceType());
int dsedHeaderLength = dsedHeader2.getDsedHeaderLength();
int subHeaderType = dsedHeader2.getSubHeaderType();
int subHeaderLength = dsedHeader2.getSubHeaderLength();
try {
dsedHeader2 = new DeviceSecurityEventDataHeader2(dsedBytes);
headerInfo = dsedHeader2.toString();
subHeaderInfo = "\nSub header type: " + subHeaderType;
setDeviceType(dsedHeader2.getDeviceType());
int dsedHeaderLength = dsedHeader2.getDsedHeaderLength();
int subHeaderType = dsedHeader2.getSubHeaderType();
int subHeaderLength = dsedHeader2.getSubHeaderLength();
byte[] dsedSubHeaderBytes = new byte[subHeaderLength];
System.arraycopy(dsedBytes, dsedHeaderLength, dsedSubHeaderBytes, 0, subHeaderLength);
subHeaderInfo = "\nSub header type: " + subHeaderType;
if (subHeaderType == SUBHEADERTYPE_MEAS_BLOCK) {
dsedSubHeader = new DeviceSecurityEventDataSubHeaderSpdmMeasurementBlock(dsedSubHeaderBytes);
subHeaderInfo += dsedSubHeader.toString();
byte[] dsedSubHeaderBytes = new byte[subHeaderLength];
System.arraycopy(dsedBytes, dsedHeaderLength, dsedSubHeaderBytes, 0, subHeaderLength);
if (subHeaderType == SUBHEADERTYPE_MEAS_BLOCK) {
try {
dsedSubHeader = new DeviceSecurityEventDataSubHeaderSpdmMeasurementBlock(dsedSubHeaderBytes);
subHeaderInfo += dsedSubHeader.toString();
}
catch(NullPointerException e) {
subHeaderInfo = " Could not interpret Sub header info";
}
}
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);
}
else if (subHeaderType == SUBHEADERTYPE_CERT_CHAIN) {
// dsedSubHeader = new DeviceSecurityEventDataSubHeaderCertChain();
subHeaderInfo += " Cert chain to be implemented ";
catch(NullPointerException e) {
headerInfo = " Could not interpret Header info";
}
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);
}
/**
@ -88,8 +107,8 @@ public class DeviceSecurityEventData2 extends DeviceSecurityEvent {
*/
public String toString() {
String dsedInfo = "";
dsedInfo += dsedHeader2.toString();
dsedInfo += dsedSubHeader.toString();
dsedInfo += headerInfo;
dsedInfo += subHeaderInfo;
dsedInfo += getDeviceContextInfo();
return dsedInfo;
}

View File

@ -5,6 +5,7 @@ import hirs.utils.tpm.eventlog.spdm.SpdmHa;
import hirs.utils.tpm.eventlog.spdm.SpdmMeasurementBlock;
import hirs.utils.tpm.eventlog.uefi.UefiConstants;
import lombok.Getter;
import org.apache.commons.lang3.ObjectUtils;
import java.io.ByteArrayInputStream;
import java.io.IOException;
@ -48,6 +49,12 @@ public class DeviceSecurityEventDataHeader extends DeviceSecurityEventHeader {
*/
private SpdmMeasurementBlock spdmMeasurementBlock = null;
/**
* Human-readable description of the data within the
* SpdmMeasurementBlock.
*/
private String spdmMeasurementBlockInfo = "";
/**
* DeviceSecurityEventDataHeader Constructor.
*
@ -83,7 +90,13 @@ public class DeviceSecurityEventDataHeader extends DeviceSecurityEventHeader {
ByteArrayInputStream spdmMeasurementBlockData =
new ByteArrayInputStream(spdmMeasBlockBytes);
spdmMeasurementBlock = new SpdmMeasurementBlock(spdmMeasurementBlockData);
try {
spdmMeasurementBlock = new SpdmMeasurementBlock(spdmMeasurementBlockData);
spdmMeasurementBlockInfo = spdmMeasurementBlock.toString();
}
catch(NullPointerException e) {
spdmMeasurementBlockInfo = "Could not interpret SPDM Measurement Block info";
}
int devPathLenStartByte = 28 + sizeOfSpdmMeasBlock;
extractDevicePathAndFinalSize(dsedBytes, devPathLenStartByte);
@ -101,7 +114,7 @@ public class DeviceSecurityEventDataHeader extends DeviceSecurityEventHeader {
String spdmHashAlgoStr = SpdmHa.tcgAlgIdToString(spdmHashAlgo);
dsedHeaderInfo += "\n SPDM Hash Algorithm = " + spdmHashAlgoStr;
dsedHeaderInfo += "\n SPDM Measurement Block:";
dsedHeaderInfo += spdmMeasurementBlock.toString();
dsedHeaderInfo += spdmMeasurementBlockInfo;
return dsedHeaderInfo;
}

View File

@ -38,10 +38,10 @@ public class EvEfiSpdmDeviceSecurityEvent {
/**
* Signature (text) data.
*/
private String signature = "";
private String dsedSignature = "";
/**
* 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.
*/
String spdmInfo = "";
@ -49,49 +49,48 @@ public class EvEfiSpdmDeviceSecurityEvent {
* EvEfiSpdmFirmwareBlob constructor.
*
* @param eventData byte array holding the event to process.
* @throws java.io.UnsupportedEncodingException if input fails to parse.
*/
public EvEfiSpdmDeviceSecurityEvent(final byte[] eventData) {
byte[] signatureBytes = new byte[UefiConstants.SIZE_16];
System.arraycopy(eventData, 0, signatureBytes, 0, UefiConstants.SIZE_16);
signature = new String(signatureBytes, StandardCharsets.UTF_8);
signature = signature.replaceAll("[^\\P{C}\t\r\n]", ""); // remove null characters
byte[] dsedSignatureBytes = new byte[UefiConstants.SIZE_16];
System.arraycopy(eventData, 0, dsedSignatureBytes, 0, UefiConstants.SIZE_16);
dsedSignature = new String(dsedSignatureBytes, StandardCharsets.UTF_8);
dsedSignature = dsedSignature.replaceAll("[^\\P{C}\t\r\n]", ""); // remove null characters
byte[] versionBytes = new byte[UefiConstants.SIZE_2];
System.arraycopy(eventData, UefiConstants.OFFSET_16, versionBytes, 0,
byte[] dsedVersionBytes = new byte[UefiConstants.SIZE_2];
System.arraycopy(eventData, UefiConstants.OFFSET_16, dsedVersionBytes, 0,
UefiConstants.SIZE_2);
String version = HexUtils.byteArrayToHexString(versionBytes);
if (version == "") {
version = "version not readable";
String dsedVersion = HexUtils.byteArrayToHexString(dsedVersionBytes);
if (dsedVersion == "") {
dsedVersion = "version not readable";
}
if (signature.contains("SPDM Device Sec2")) {
if (dsedSignature.contains("SPDM Device Sec2")) {
spdmInfo = " Signature = SPDM Device Sec2";
if (version.equals("0200")) {
if (dsedVersion.equals("0200")) {
dsed = new DeviceSecurityEventData2(eventData);
spdmInfo += dsed.toString();
}
else {
spdmInfo += " Incompatible version for DeviceSecurityEventData2: " + version;
spdmInfo += " Incompatible version for DeviceSecurityEventData2: " + dsedVersion;
}
}
else if (signature.contains("SPDM Device Sec")) { // implies Device Security event
else if (dsedSignature.contains("SPDM Device Sec")) { // implies Device Security event
spdmInfo = " Signature = SPDM Device Sec";
if (version.equals("0100")) {
if (dsedVersion.equals("0100")) {
dsed = new DeviceSecurityEventData(eventData);
spdmInfo += dsed.toString();
}
else {
spdmInfo += " Incompatible version for DeviceSecurityEventData: " + version;
spdmInfo += " Incompatible version for DeviceSecurityEventData: " + dsedVersion;
}
}
else {
spdmInfo = " Signature = Undetermined value: " + signature;
spdmInfo = " Signature = Undetermined value: " + dsedSignature;
}
}

View File

@ -7,12 +7,15 @@ import java.io.UnsupportedEncodingException;
import java.nio.charset.StandardCharsets;
/**
* Class to process the EV_NO_ACTION event using a structure of TCG_EfiSpecIDEvent.
* Class to process the EV_NO_ACTION event.
* The first 16 bytes of the event data MUST be a String based identifier (Signature).
* The only currently defined Signature is "Spec ID Event03"
* which implies the data is a TCG_EfiSpecIDEvent.
* TCG_EfiSpecIDEvent is the first event in a TPM Event Log and is used to determine
* if the format of the Log (SHA1 vs Crypto Agile).
* The only currently defined Signatures are
* 1) "Spec ID Event03"
* - implies the data is a TCG_EfiSpecIDEvent
* - TCG_EfiSpecIDEvent is the first event in a TPM Event Log and is used to determine
* if the format of the Log (SHA1 vs Crypto Agile).
* 2) "NvIndexInstance"
* - implies the data is a NV_INDEX_INSTANCE_EVENT_LOG_DATA
* <p>
* Notes:
* 1. First 16 bytes of the structure is an ASCII with a fixed Length of 16
@ -28,11 +31,20 @@ public class EvNoAction {
* True of the event is a SpecIDEvent.
*/
private boolean bSpecIDEvent = false;
/**
* True of the event is a NvIndexInstance.
*/
private boolean bNvIndexInstance = false;
/**
* EvEfiSpecIdEvent Object.
*/
@Getter
private EvEfiSpecIdEvent specIDEvent = null;
/**
* NvIndexInstanceEvent Object.
*/
@Getter
private NvIndexInstanceEventLogData nvIndexInstanceEvent = null;
/**
* EvNoAction constructor.
@ -49,7 +61,8 @@ public class EvNoAction {
specIDEvent = new EvEfiSpecIdEvent(eventData);
bSpecIDEvent = true;
} else if (signature.contains("NvIndexInstance")) {
System.out.println("XXXX Nv Index Instance");
nvIndexInstanceEvent = new NvIndexInstanceEventLogData(eventData);
bNvIndexInstance = true;
}
}
@ -68,21 +81,23 @@ public class EvNoAction {
* @return Human readable description of this event.
*/
public String toString() {
String specInfo = "";
String noActionInfo = "";
if (bSpecIDEvent) {
specInfo += " Signature = Spec ID Event03 : ";
noActionInfo += " Signature = Spec ID Event03 : ";
if (specIDEvent.isCryptoAgile()) {
specInfo += "Log format is Crypto Agile\n";
noActionInfo += "Log format is Crypto Agile\n";
} else {
specInfo += "Log format is SHA 1 (NOT Crypto Agile)\n";
noActionInfo += "Log format is SHA 1 (NOT Crypto Agile)\n";
}
specInfo += " Platform Profile Specification version = "
noActionInfo += " Platform Profile Specification version = "
+ specIDEvent.getVersionMajor() + "." + specIDEvent.getVersionMinor()
+ " using errata version " + specIDEvent.getErrata();
} else if (bNvIndexInstance) {
noActionInfo = nvIndexInstanceEvent.toString();
} else {
specInfo = "EV_NO_ACTION event named " + signature
noActionInfo = "EV_NO_ACTION event named " + signature
+ " encountered but support for processing it has not been added to this application.\n";
}
return specInfo;
return noActionInfo;
}
}

View File

@ -1,47 +1,113 @@
package hirs.utils.tpm.eventlog.events;
import hirs.utils.HexUtils;
import hirs.utils.tpm.eventlog.uefi.UefiConstants;
import java.nio.charset.StandardCharsets;
/**
* Class to process the NV_INDEX_INSTANCE_EVENT_LOG_DATA per PFP.
* The first 16 bytes of the event data header are 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.
* Per PFP, the first 16 bytes of the structure are a String based identifier (Signature),
* which are a NULL-terminated ASCII string "NvIndexInstance".
*
* HEADERS defined by PFP v1.06 Rev 52.
* Certain fields are common to both ..HEADER and ..HEADER2, and are noted below the structures.
* <p>
* typedef struct tdDEVICE_SECURITY_EVENT_DATA_HEADER {
* UINT8 Signature[16];
* typedef struct tdNV_INDEX_INSTANCE_EVENT_LOG_DATA {
* BYTE Signature[16];
* UINT16 Version;
* UINT16 Length;
* UINT32 SpdmHashAlg;
* UINT32 DeviceType;
* SPDM_MEASUREMENT_BLOCK SpdmMeasurementBlock;
* UINT64 DevicePathLength;
* UNIT8 DevicePath[DevicePathLength]
* } DEVICE_SECURITY_EVENT_DATA_HEADER;
* <p>
* typedef struct tdDEVICE_SECURITY_EVENT_DATA_HEADER2 { - NOT IMPLEMENTED YET
* 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;
* <p>
* Fields common to both ..HEADER and ..HEADER2:
* Signature
* Version
* DeviceType
* DevicePathLength
* DevicePath
* UINT8[6] Reserved;
* DEVICE_SECURITY_EVENT_DATA2 Data;
* } NV_INDEX_INSTANCE_EVENT_LOG_DATA;
* <p>
*/
public class NvIndexInstanceEventLogData {
/**
* DeviceSecurityEventData2 Object.
*/
// private DeviceSecurityEventData2 dsed = null;
private DeviceSecurityEvent dsed = null;
/**
* Signature (text) data.
*/
private String signature = "";
/**
* Version.
*/
private String version = "";
/**
* Human-readable description of the data within this DEVICE_SECURITY_EVENT_DATA/..DATA2 event.
*/
String nvIndexInstanceInfo = "";
/**
* NvIndexInstanceEventLogData constructor.
*
* @param eventData byte array holding the event to process.
*/
public NvIndexInstanceEventLogData(final byte[] eventData) {
byte[] signatureBytes = new byte[16];
System.arraycopy(eventData, 0, signatureBytes, 0, 16);
signature = new String(signatureBytes, StandardCharsets.UTF_8);
signature = signature.replaceAll("[^\\P{C}\t\r\n]", ""); // remove null characters
byte[] versionBytes = new byte[2];
System.arraycopy(eventData, 16, versionBytes, 0, 2);
String version = HexUtils.byteArrayToHexString(versionBytes);
if (version == "") {
version = "version not readable";
}
// 6 bytes of Reserved data
byte[] dsedSignatureBytes = new byte[16];
System.arraycopy(eventData, 24, dsedSignatureBytes, 0, 16);
String dsedSignature = new String(dsedSignatureBytes, StandardCharsets.UTF_8);
dsedSignature = dsedSignature.replaceAll("[^\\P{C}\t\r\n]", ""); // remove null characters
byte[] dsedVersionBytes = new byte[2];
System.arraycopy(eventData, 40, dsedVersionBytes, 0, 2);
String dsedVersion = HexUtils.byteArrayToHexString(dsedVersionBytes);
if (dsedVersion == "") {
dsedVersion = "version not readable";
}
if (dsedSignature.contains("SPDM Device Sec2")) {
int dsedEventDataSize = eventData.length - 24;
byte[] dsedEventData = new byte[dsedEventDataSize];
System.arraycopy(eventData, 24, dsedEventData, 0, dsedEventDataSize);
nvIndexInstanceInfo = " Signature = SPDM Device Sec2";
if (dsedVersion.equals("0200")) {
// TODO this is throwing a nullPointerException
dsed = new DeviceSecurityEventData2(dsedEventData);
nvIndexInstanceInfo += dsed.toString();
}
else {
nvIndexInstanceInfo += " Incompatible version for DeviceSecurityEventData2: "
+ dsedVersion;
}
}
else {
nvIndexInstanceInfo = " Signature error: should be \'SPDM Device Sec2\' but is "
+ signature;
}
}
/**
* Returns a description of this event.
*
* @return Human-readable description of this event.
*/
public String toString() {
return nvIndexInstanceInfo;
}
}