mirror of
https://github.com/nsacyber/HIRS.git
synced 2024-12-18 20:47:58 +00:00
Merge pull request #819 from nsacyber/v3_issue_804-spdm
Add processing for EV_EFI_NOACTION_NvIndexInstance and SPDM Cert Chain data structure
This commit is contained in:
commit
fcd0c6f50e
@ -43,17 +43,16 @@ dependencies {
|
||||
implementation 'org.apache.logging.log4j:log4j-core:2.19.0'
|
||||
implementation 'org.apache.logging.log4j:log4j-api:2.19.0'
|
||||
implementation 'org.glassfish.jaxb:jaxb-runtime:4.0.1'
|
||||
implementation 'org.slf4j:slf4j-simple:1.7.30'
|
||||
|
||||
testImplementation 'org.junit.jupiter:junit-jupiter:5.9.3'
|
||||
testImplementation 'org.junit.platform:junit-platform-launcher:1.9.3'
|
||||
testImplementation 'org.hamcrest:hamcrest:2.2'
|
||||
testImplementation project(path: ':HIRS_AttestationCA')
|
||||
|
||||
testImplementation 'org.mockito:mockito-core:4.2.0'
|
||||
testImplementation project(path: ':HIRS_AttestationCA')
|
||||
|
||||
compileOnly libs.lombok
|
||||
annotationProcessor libs.lombok
|
||||
|
||||
}
|
||||
|
||||
checkstyle {
|
||||
|
@ -179,9 +179,9 @@ public final class PciIds {
|
||||
|
||||
String classCode = refClassCode;
|
||||
if (classCode != null && classCode.trim().matches("^[0-9A-Fa-f]{6}$")) {
|
||||
String deviceClass = classCode.substring(0,2).toLowerCase();
|
||||
String deviceSubclass = classCode.substring(2,4).toLowerCase();
|
||||
String programInterface = classCode.substring(4,6).toLowerCase();
|
||||
String deviceClass = classCode.substring(0, 2).toLowerCase();
|
||||
String deviceSubclass = classCode.substring(2, 4).toLowerCase();
|
||||
String programInterface = classCode.substring(4, 6).toLowerCase();
|
||||
translatedClassCode.add(deviceClass);
|
||||
translatedClassCode.add(deviceSubclass);
|
||||
translatedClassCode.add(programInterface);
|
||||
|
@ -169,9 +169,10 @@ public final class TCGEventLog {
|
||||
// the if statement is executed
|
||||
// [new event file status = eventList.get(eventNumber-1).getVendorTableFileStatus()]
|
||||
// (ie. if the new file status is not-accessible or from-code, then want to update)
|
||||
if((vendorTableFileStatus != FILESTATUS_NOT_ACCESSIBLE) &&
|
||||
(eventList.get(eventNumber-1).getVendorTableFileStatus() != FILESTATUS_FROM_FILESYSTEM)) {
|
||||
vendorTableFileStatus = eventList.get(eventNumber-1).getVendorTableFileStatus();
|
||||
if ((vendorTableFileStatus != FILESTATUS_NOT_ACCESSIBLE)
|
||||
&& (eventList.get(eventNumber - 1).getVendorTableFileStatus()
|
||||
!= FILESTATUS_FROM_FILESYSTEM)) {
|
||||
vendorTableFileStatus = eventList.get(eventNumber - 1).getVendorTableFileStatus();
|
||||
}
|
||||
}
|
||||
calculatePcrValues();
|
||||
|
@ -6,7 +6,6 @@ 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.EvEfiSpdmDeviceSecurityEvent;
|
||||
import hirs.utils.tpm.eventlog.events.EvEfiSpecIdEvent;
|
||||
import hirs.utils.tpm.eventlog.events.EvEventTag;
|
||||
import hirs.utils.tpm.eventlog.events.EvIPL;
|
||||
import hirs.utils.tpm.eventlog.events.EvNoAction;
|
||||
@ -113,7 +112,6 @@ public class TpmPcrEvent {
|
||||
* Event hash for Crypto Agile events.
|
||||
*/
|
||||
private byte[] eventDataSha256hash;
|
||||
private EvPostCode evPostCode;
|
||||
@Setter @Getter
|
||||
private int eventNumber;
|
||||
@Setter @Getter
|
||||
@ -232,7 +230,7 @@ public class TpmPcrEvent {
|
||||
*/
|
||||
protected void setEventContent(final byte[] eventData) {
|
||||
eventContent = new byte[eventData.length];
|
||||
evPostCode = new EvPostCode(eventContent);
|
||||
//EvPostCode evPostCode = new EvPostCode(eventContent);
|
||||
System.arraycopy(eventData, 0, eventContent, 0, eventData.length);
|
||||
}
|
||||
|
||||
@ -268,12 +266,8 @@ public class TpmPcrEvent {
|
||||
noAction = new EvNoAction(eventContent);
|
||||
sb.append(noAction.toString());
|
||||
if (noAction.isSpecIDEvent()) {
|
||||
// this should be in the constructor
|
||||
EvEfiSpecIdEvent specID = noAction.getSpecIDEvent();
|
||||
specVersion = String.format("%s.%s",
|
||||
specID.getVersionMajor(),
|
||||
specID.getVersionMinor());
|
||||
specErrataVersion = specID.getErrata();
|
||||
specVersion = noAction.getSpecVersion();
|
||||
specErrataVersion = noAction.getSpecErrataVersion();
|
||||
}
|
||||
} catch (UnsupportedEncodingException ueEx) {
|
||||
log.error(ueEx);
|
||||
@ -324,23 +318,6 @@ public class TpmPcrEvent {
|
||||
case EvConstants.EV_EFI_EVENT_BASE:
|
||||
break;
|
||||
case EvConstants.EV_EFI_VARIABLE_DRIVER_CONFIG:
|
||||
UefiVariable efiVar = null;
|
||||
try {
|
||||
efiVar = new UefiVariable(eventContent);
|
||||
String efiVarDescription = efiVar.toString().replace("\n", "\n ");
|
||||
sb.append(efiVarDescription.substring(0,
|
||||
efiVarDescription.length() - INDENT_3));
|
||||
} catch (CertificateException cEx) {
|
||||
log.error(cEx);
|
||||
sb.append(cEx.toString());
|
||||
} catch (NoSuchAlgorithmException noSaEx) {
|
||||
log.error(noSaEx);
|
||||
sb.append(noSaEx.toString());
|
||||
} catch (IOException ioEx) {
|
||||
log.error(ioEx);
|
||||
sb.append(ioEx.toString());
|
||||
}
|
||||
break;
|
||||
case EvConstants.EV_EFI_VARIABLE_BOOT:
|
||||
case EvConstants.EV_EFI_VARIABLE_AUTHORITY:
|
||||
case EvConstants.EV_EFI_SPDM_DEVICE_POLICY:
|
||||
@ -458,9 +435,8 @@ public class TpmPcrEvent {
|
||||
EvNoAction noAction = new EvNoAction(content);
|
||||
description += "Event Content:\n" + noAction.toString();
|
||||
if (noAction.isSpecIDEvent()) {
|
||||
EvEfiSpecIdEvent specID = noAction.getSpecIDEvent();
|
||||
specVersion = specID.getVersionMajor() + "." + specID.getVersionMinor();
|
||||
specErrataVersion = specID.getErrata();
|
||||
specVersion = noAction.getSpecVersion();
|
||||
specErrataVersion = noAction.getSpecErrataVersion();
|
||||
}
|
||||
break;
|
||||
case EvConstants.EV_SEPARATOR:
|
||||
@ -514,28 +490,19 @@ public class TpmPcrEvent {
|
||||
case EvConstants.EV_EFI_EVENT_BASE:
|
||||
break;
|
||||
case EvConstants.EV_EFI_VARIABLE_DRIVER_CONFIG:
|
||||
UefiVariable efiVar = new UefiVariable(content);
|
||||
String efiVarDescription = efiVar.toString().replace("\n", "\n ");
|
||||
description += "Event Content:\n " + efiVarDescription.substring(0,
|
||||
efiVarDescription.length() - INDENT_3);
|
||||
vendorTableFileStatus = efiVar.getVendorTableFileStatus();
|
||||
break;
|
||||
case EvConstants.EV_EFI_VARIABLE_BOOT:
|
||||
case EvConstants.EV_EFI_VARIABLE_AUTHORITY:
|
||||
case EvConstants.EV_EFI_SPDM_DEVICE_POLICY:
|
||||
case EvConstants.EV_EFI_SPDM_DEVICE_AUTHORITY:
|
||||
UefiVariable efiVar2 = new UefiVariable(content);
|
||||
description += "Event Content:\n" + efiVar2.toString();
|
||||
vendorTableFileStatus = efiVar2.getVendorTableFileStatus();
|
||||
UefiVariable efiVar = new UefiVariable(content);
|
||||
description += "Event Content:\n" + efiVar.toString();
|
||||
vendorTableFileStatus = efiVar.getVendorTableFileStatus();
|
||||
break;
|
||||
case EvConstants.EV_EFI_BOOT_SERVICES_APPLICATION:
|
||||
case EvConstants.EV_EFI_BOOT_SERVICES_DRIVER:
|
||||
EvEfiBootServicesApp bootServices = new EvEfiBootServicesApp(content);
|
||||
description += "Event Content:\n" + bootServices.toString();
|
||||
break;
|
||||
case EvConstants.EV_EFI_BOOT_SERVICES_DRIVER: // same as EV_EFI_BOOT_SERVICES_APP
|
||||
EvEfiBootServicesApp bootDriver = new EvEfiBootServicesApp(content);
|
||||
description += "Event Content:\n" + bootDriver.toString();
|
||||
break;
|
||||
case EvConstants.EV_EFI_RUNTIME_SERVICES_DRIVER:
|
||||
break;
|
||||
case EvConstants.EV_EFI_GPT_EVENT:
|
||||
@ -555,10 +522,6 @@ 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();
|
||||
break;
|
||||
case EvConstants.EV_EFI_SPDM_FIRMWARE_CONFIG:
|
||||
description += "Event Content:\n" + new EvEfiSpdmDeviceSecurityEvent(content).toString();
|
||||
break;
|
||||
|
@ -3,11 +3,6 @@ package hirs.utils.tpm.eventlog.events;
|
||||
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;
|
||||
|
||||
|
||||
/**
|
||||
* 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.
|
||||
@ -17,10 +12,10 @@ import static hirs.utils.tpm.eventlog.events.DeviceSecurityEventHeader.DEVICE_TY
|
||||
* 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.
|
||||
* per PFP. The only currently defined Signatures are "SPDM Device Sec" and "SPDM Device Sec2",
|
||||
* which implies the data is a DEVICE_SECURITY_EVENT_DATA or ..DATA2, respectively.
|
||||
* Field 2:
|
||||
* The Version field indicates whether the Device Security Event is ..DATA or ..DATA2.
|
||||
* The Version field also indicates whether the Device Security Event is ..DATA or ..DATA2.
|
||||
*
|
||||
* DEVICE SECURITY EVENT structures defined by PFP v1.06 Rev 52:
|
||||
* <p>
|
||||
@ -39,19 +34,9 @@ import static hirs.utils.tpm.eventlog.events.DeviceSecurityEventHeader.DEVICE_TY
|
||||
* UINT8 Signature[16];
|
||||
* UINT16 Version;
|
||||
* ... ...
|
||||
* (The rest of the components are different for HEADER vs HEADER2)
|
||||
* }
|
||||
* <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 {
|
||||
|
||||
@ -73,7 +58,7 @@ public abstract class DeviceSecurityEvent {
|
||||
* DEVICE_SECURITY_EVENT_DATA_DEVICE_CONTEXT. DEVICE can be either PCI or USB.
|
||||
*/
|
||||
@Getter
|
||||
String deviceContextInfo = "";
|
||||
private String deviceContextInfo = "";
|
||||
|
||||
/**
|
||||
* DeviceSecurityEventData Default Constructor.
|
||||
@ -91,22 +76,19 @@ public abstract class DeviceSecurityEvent {
|
||||
*/
|
||||
public void instantiateDeviceContext(final byte[] dsedDeviceContextBytes) {
|
||||
|
||||
if (deviceType == DEVICE_TYPE_NONE) {
|
||||
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();
|
||||
}
|
||||
else if (deviceType == DEVICE_TYPE_USB) {
|
||||
// dsedDevContext
|
||||
// = new DeviceSecurityEventDataUsbContext(dsedDeviceContextBytes);
|
||||
// deviceContextInfo = dsedDevContext.toString();
|
||||
deviceContextInfo = " Device Type: USB - To be implemented";
|
||||
}
|
||||
else {
|
||||
deviceContextInfo = " Unknown device type; cannot process device context";
|
||||
if (dsedDeviceContextBytes.length == 0) {
|
||||
deviceContextInfo = "\n DeviceSecurityEventDataDeviceContext object is empty";
|
||||
} else {
|
||||
if (deviceType == DeviceSecurityEventDataDeviceContext.DEVICE_TYPE_NONE) {
|
||||
deviceContextInfo = "\n No Device Context (indicated by device type value of 0)";
|
||||
} else if (deviceType == DeviceSecurityEventDataDeviceContext.DEVICE_TYPE_PCI) {
|
||||
dsedDevContext = new DeviceSecurityEventDataPciContext(dsedDeviceContextBytes);
|
||||
deviceContextInfo = dsedDevContext.toString();
|
||||
} else if (deviceType == DeviceSecurityEventDataDeviceContext.DEVICE_TYPE_USB) {
|
||||
deviceContextInfo = " Device Type: USB - To be implemented";
|
||||
} else {
|
||||
deviceContextInfo = " Unknown device type; cannot process device context";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2,9 +2,6 @@ package hirs.utils.tpm.eventlog.events;
|
||||
|
||||
import lombok.Getter;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
|
||||
/**
|
||||
* Class to process DEVICE_SECURITY_EVENT_DATA.
|
||||
* Parses event data per PFP v1.06 Rev52 Table 20.
|
||||
@ -23,22 +20,36 @@ public class DeviceSecurityEventData extends DeviceSecurityEvent {
|
||||
@Getter
|
||||
private DeviceSecurityEventDataHeader dsedHeader = null;
|
||||
|
||||
/**
|
||||
* Human-readable description of the data within the
|
||||
* DEVICE_SECURITY_EVENT_DATA_HEADER.
|
||||
*/
|
||||
@Getter
|
||||
private 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);
|
||||
if (dsedBytes.length == 0) {
|
||||
headerInfo = " DeviceSecurityEventData object is empty";
|
||||
} else {
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -47,8 +58,7 @@ public class DeviceSecurityEventData extends DeviceSecurityEvent {
|
||||
* @return a description of this structure.
|
||||
*/
|
||||
public String toString() {
|
||||
String dsedInfo = "";
|
||||
dsedInfo += dsedHeader.toString();
|
||||
String dsedInfo = headerInfo;
|
||||
dsedInfo += getDeviceContextInfo();
|
||||
return dsedInfo;
|
||||
}
|
||||
|
@ -2,12 +2,6 @@ package hirs.utils.tpm.eventlog.events;
|
||||
|
||||
import lombok.Getter;
|
||||
|
||||
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.
|
||||
* Parses event data per PFP v1.06 Rev52 Table 26.
|
||||
@ -34,13 +28,20 @@ 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
|
||||
private 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
|
||||
*/
|
||||
@Getter
|
||||
String subHeaderInfo = "";
|
||||
private String subHeaderInfo = "";
|
||||
|
||||
/**
|
||||
* DeviceSecurityEventData2 Constructor.
|
||||
@ -49,36 +50,41 @@ 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();
|
||||
if (dsedBytes.length == 0) {
|
||||
headerInfo = " DeviceSecurityEventData2 object is empty";
|
||||
} else {
|
||||
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 = " Sub header type: "
|
||||
+ DeviceSecurityEventDataSubHeader.subheaderTypeToString(subHeaderType) + "\n";
|
||||
|
||||
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 == DeviceSecurityEventDataSubHeader.SUBHEADERTYPE_MEAS_BLOCK) {
|
||||
dsedSubHeader = new DeviceSecurityEventDataSubHeaderSpdmMeasurementBlock(dsedSubHeaderBytes);
|
||||
subHeaderInfo += dsedSubHeader.toString();
|
||||
} else if (subHeaderType == DeviceSecurityEventDataSubHeader.SUBHEADERTYPE_CERT_CHAIN) {
|
||||
dsedSubHeader = new DeviceSecurityEventDataSubHeaderCertChain(dsedSubHeaderBytes);
|
||||
subHeaderInfo += dsedSubHeader.toString();
|
||||
} else {
|
||||
subHeaderInfo += " Sub header type unknown\n";
|
||||
}
|
||||
|
||||
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 ";
|
||||
}
|
||||
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);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -87,9 +93,8 @@ public class DeviceSecurityEventData2 extends DeviceSecurityEvent {
|
||||
* @return a description of this structure.
|
||||
*/
|
||||
public String toString() {
|
||||
String dsedInfo = "";
|
||||
dsedInfo += dsedHeader2.toString();
|
||||
dsedInfo += dsedSubHeader.toString();
|
||||
String dsedInfo = headerInfo;
|
||||
dsedInfo += subHeaderInfo;
|
||||
dsedInfo += getDeviceContextInfo();
|
||||
return dsedInfo;
|
||||
}
|
||||
|
@ -28,6 +28,19 @@ public abstract class DeviceSecurityEventDataDeviceContext {
|
||||
@Getter
|
||||
private int length = 0;
|
||||
|
||||
/**
|
||||
* Device Security Event Data Device Type = no device type.
|
||||
*/
|
||||
public static final int DEVICE_TYPE_NONE = 0;
|
||||
/**
|
||||
* Device Security Event Data Device Type = DEVICE_TYPE_PCI.
|
||||
*/
|
||||
public static final int DEVICE_TYPE_PCI = 1;
|
||||
/**
|
||||
* Device Security Event Data Device Type = DEVICE_TYPE_USB.
|
||||
*/
|
||||
public static final int DEVICE_TYPE_USB = 2;
|
||||
|
||||
/**
|
||||
* DeviceSecurityEventDataDeviceContext Constructor.
|
||||
*
|
||||
@ -45,17 +58,16 @@ public abstract class DeviceSecurityEventDataDeviceContext {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a human readable description of the data common to device context structures.
|
||||
* Returns a human-readable description of the data common to device context structures.
|
||||
*
|
||||
* @return a description of this structure..
|
||||
* @return a description of this structure.
|
||||
*/
|
||||
public String toString() {
|
||||
String dSEDdeviceContextCommonInfo = "";
|
||||
|
||||
dSEDdeviceContextCommonInfo += "\n DeviceSecurityEventData Device Context:";
|
||||
dSEDdeviceContextCommonInfo += " DeviceSecurityEventData Device Context:\n";
|
||||
|
||||
return dSEDdeviceContextCommonInfo;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
@ -8,7 +8,6 @@ import lombok.Getter;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
|
||||
/**
|
||||
* Class to process the DEVICE_SECURITY_EVENT_DATA_HEADER.
|
||||
@ -48,6 +47,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 +88,13 @@ public class DeviceSecurityEventDataHeader extends DeviceSecurityEventHeader {
|
||||
|
||||
ByteArrayInputStream spdmMeasurementBlockData =
|
||||
new ByteArrayInputStream(spdmMeasBlockBytes);
|
||||
spdmMeasurementBlock = new SpdmMeasurementBlock(spdmMeasurementBlockData);
|
||||
|
||||
try {
|
||||
spdmMeasurementBlock = new SpdmMeasurementBlock(spdmMeasurementBlockData);
|
||||
spdmMeasurementBlockInfo = spdmMeasurementBlock.toString();
|
||||
} catch (IOException e) {
|
||||
spdmMeasurementBlockInfo = " Error reading SPDM Measurement Block";
|
||||
}
|
||||
|
||||
int devPathLenStartByte = 28 + sizeOfSpdmMeasBlock;
|
||||
extractDevicePathAndFinalSize(dsedBytes, devPathLenStartByte);
|
||||
@ -95,13 +106,11 @@ public class DeviceSecurityEventDataHeader extends DeviceSecurityEventHeader {
|
||||
* @return a description of this structure.
|
||||
*/
|
||||
public String toString() {
|
||||
String dsedHeaderInfo = "";
|
||||
|
||||
dsedHeaderInfo += super.toString();
|
||||
String dsedHeaderInfo = super.toString();
|
||||
String spdmHashAlgoStr = SpdmHa.tcgAlgIdToString(spdmHashAlgo);
|
||||
dsedHeaderInfo += "\n SPDM Hash Algorithm = " + spdmHashAlgoStr;
|
||||
dsedHeaderInfo += "\n SPDM Measurement Block:";
|
||||
dsedHeaderInfo += spdmMeasurementBlock.toString();
|
||||
dsedHeaderInfo += " SPDM Hash Algorithm = " + spdmHashAlgoStr + "\n";
|
||||
dsedHeaderInfo += " SPDM Measurement Block:\n";
|
||||
dsedHeaderInfo += spdmMeasurementBlockInfo;
|
||||
|
||||
return dsedHeaderInfo;
|
||||
}
|
||||
|
@ -3,8 +3,6 @@ package hirs.utils.tpm.eventlog.events;
|
||||
import hirs.utils.HexUtils;
|
||||
import lombok.Getter;
|
||||
|
||||
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
|
||||
@ -30,7 +28,7 @@ import java.io.UnsupportedEncodingException;
|
||||
public class DeviceSecurityEventDataHeader2 extends DeviceSecurityEventHeader {
|
||||
|
||||
/**
|
||||
* Event auth state
|
||||
* Event auth state.
|
||||
*/
|
||||
@Getter
|
||||
private int authState = 0;
|
||||
@ -40,10 +38,12 @@ public class DeviceSecurityEventDataHeader2 extends DeviceSecurityEventHeader {
|
||||
@Getter
|
||||
private int length = 0;
|
||||
/**
|
||||
* Event sub headerType
|
||||
* Event sub headerType.
|
||||
* SUBHEADERTYPE_MEAS_BLOCK = 0
|
||||
* SUBHEADERTYPE_CERT_CHAIN = 1
|
||||
*/
|
||||
@Getter
|
||||
private int subHeaderType = 0;
|
||||
private int subHeaderType = -1;
|
||||
/**
|
||||
* Event sub header length.
|
||||
*/
|
||||
@ -56,12 +56,12 @@ public class DeviceSecurityEventDataHeader2 extends DeviceSecurityEventHeader {
|
||||
private String subHeaderUid = "";
|
||||
|
||||
/**
|
||||
* Auth state - success
|
||||
* 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
|
||||
* validated with the entry in the UEFI device signature variable.
|
||||
*/
|
||||
public static final int AUTH_NO_AUTHORITY = 1;
|
||||
/**
|
||||
@ -70,27 +70,23 @@ public class DeviceSecurityEventDataHeader2 extends DeviceSecurityEventHeader {
|
||||
*/
|
||||
public static final int AUTH_NO_BINDING = 2;
|
||||
/**
|
||||
* Auth state - data has no digital signature
|
||||
* Auth state - data has no digital signature.
|
||||
*/
|
||||
public static final int AUTH_FAIL_NO_SIG = 3;
|
||||
/**
|
||||
* Auth state - data is invalid
|
||||
* Auth state - data is invalid.
|
||||
*/
|
||||
public static final int AUTH_FAIL_INVALID = 4;
|
||||
/**
|
||||
* Auth state - device is not an SPDM-capable device
|
||||
* 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;
|
||||
|
||||
|
||||
/**
|
||||
* DeviceSecurityEventDataHeader2 Constructor.
|
||||
*
|
||||
* @param dsedBytes byte array holding the DeviceSecurityEventData2.
|
||||
*/
|
||||
public DeviceSecurityEventDataHeader2(final byte[] dsedBytes) {
|
||||
|
||||
super(dsedBytes);
|
||||
@ -130,15 +126,18 @@ public class DeviceSecurityEventDataHeader2 extends DeviceSecurityEventHeader {
|
||||
* @return a description of this structure.
|
||||
*/
|
||||
public String toString() {
|
||||
String dsedHeader2Info = "";
|
||||
|
||||
dsedHeader2Info += super.toString();
|
||||
dsedHeader2Info += "\n AuthState: " + getAuthStateString();
|
||||
dsedHeader2Info += "\n Sub header UID: " + subHeaderUid;
|
||||
String dsedHeader2Info = super.toString();
|
||||
dsedHeader2Info += " AuthState: " + getAuthStateString() + "\n";
|
||||
dsedHeader2Info += " Sub header UID: " + subHeaderUid + "\n";
|
||||
|
||||
return dsedHeader2Info;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a human-readable description of auth state based on numeric representation lookup.
|
||||
*
|
||||
* @return a description of the auth state.
|
||||
*/
|
||||
public String getAuthStateString() {
|
||||
|
||||
switch (authState) {
|
||||
|
@ -3,7 +3,6 @@ package hirs.utils.tpm.eventlog.events;
|
||||
import hirs.utils.HexUtils;
|
||||
import lombok.Getter;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import static hirs.utils.PciIds.translateDevice;
|
||||
@ -102,7 +101,6 @@ public class DeviceSecurityEventDataPciContext extends DeviceSecurityEventDataDe
|
||||
byte[] pciSubsystemIdBytes = new byte[2];
|
||||
System.arraycopy(dSEDpciContextBytes, 14, pciSubsystemIdBytes, 0, 2);
|
||||
subsystemId = HexUtils.byteArrayToHexString(HexUtils.leReverseByte(pciSubsystemIdBytes));
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@ -114,22 +112,22 @@ public class DeviceSecurityEventDataPciContext extends DeviceSecurityEventDataDe
|
||||
String dSEDpciContextInfo = "";
|
||||
|
||||
dSEDpciContextInfo += super.toString();
|
||||
dSEDpciContextInfo += "\n Device Type = PCI";
|
||||
dSEDpciContextInfo += "\n Vendor = " + translateVendor(vendorId);
|
||||
dSEDpciContextInfo += "\n Device = " + translateDevice(vendorId, deviceId);
|
||||
dSEDpciContextInfo += "\n RevisionID = " + revisionId;
|
||||
dSEDpciContextInfo += " Device Type = PCI\n";
|
||||
dSEDpciContextInfo += " Vendor = " + translateVendor(vendorId) + "\n";
|
||||
dSEDpciContextInfo += " Device = " + translateDevice(vendorId, deviceId) + "\n";
|
||||
dSEDpciContextInfo += " RevisionID = " + revisionId + "\n";
|
||||
|
||||
List<String> classCodeList = translateDeviceClass(classCode);
|
||||
dSEDpciContextInfo += "\n Device Class: ";
|
||||
if(classCodeList.size() == 3) {
|
||||
dSEDpciContextInfo += "\n Class = " + classCodeList.get(0);
|
||||
dSEDpciContextInfo += "\n Subclass = " + classCodeList.get(1);
|
||||
dSEDpciContextInfo += "\n Programming Interface = " + classCodeList.get(2);
|
||||
dSEDpciContextInfo += " Device Class: \n";
|
||||
if (classCodeList.size() == 3) {
|
||||
dSEDpciContextInfo += " Class = " + classCodeList.get(0) + "\n";
|
||||
dSEDpciContextInfo += " Subclass = " + classCodeList.get(1) + "\n";
|
||||
dSEDpciContextInfo += " Programming Interface = " + classCodeList.get(2) + "\n";
|
||||
} else {
|
||||
dSEDpciContextInfo += " ** Class code could not be determined **";
|
||||
}
|
||||
dSEDpciContextInfo += "\n SubsystemVendor = " + translateVendor(subsystemVendorId);
|
||||
dSEDpciContextInfo += "\n Subsystem = " + translateDevice(subsystemVendorId, subsystemId);
|
||||
dSEDpciContextInfo += " SubsystemVendor = " + translateVendor(subsystemVendorId) + "\n";
|
||||
dSEDpciContextInfo += " Subsystem = " + translateDevice(subsystemVendorId, subsystemId) + "\n";
|
||||
|
||||
return dSEDpciContextInfo;
|
||||
}
|
||||
|
@ -1,6 +1,5 @@
|
||||
package hirs.utils.tpm.eventlog.events;
|
||||
|
||||
|
||||
/**
|
||||
* Class to process the DEVICE_SECURITY_EVENT_DATA_SUB_HEADER event per PFP.
|
||||
*
|
||||
@ -14,7 +13,37 @@ package hirs.utils.tpm.eventlog.events;
|
||||
*/
|
||||
public abstract class DeviceSecurityEventDataSubHeader {
|
||||
|
||||
/**
|
||||
* 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;
|
||||
|
||||
/**
|
||||
* DeviceSecurityEventDataSubHeader Default Constructor.
|
||||
*
|
||||
*/
|
||||
public DeviceSecurityEventDataSubHeader() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the device type via a lookup.
|
||||
* Lookup based upon section 10.2.7.2, Table 19, in the PFP 1.06 v52 spec.
|
||||
*
|
||||
* @param subheaderTypeInt int to convert to string
|
||||
* @return name of the device type
|
||||
*/
|
||||
public static String subheaderTypeToString(final int subheaderTypeInt) {
|
||||
switch (subheaderTypeInt) {
|
||||
case SUBHEADERTYPE_MEAS_BLOCK:
|
||||
return "SPDM Measurement Block";
|
||||
case SUBHEADERTYPE_CERT_CHAIN:
|
||||
return "SPDM Cert Chain";
|
||||
default:
|
||||
return "Unknown or invalid Subheader Type of value " + subheaderTypeInt;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,113 @@
|
||||
package hirs.utils.tpm.eventlog.events;
|
||||
|
||||
import hirs.utils.HexUtils;
|
||||
import hirs.utils.tpm.eventlog.spdm.SpdmCertificateChain;
|
||||
import hirs.utils.tpm.eventlog.spdm.SpdmHa;
|
||||
|
||||
/**
|
||||
* Class to process the DEVICE_SECURITY_EVENT_DATA_SUB_HEADER_SPDM_CERT_CHAIN event per PFP.
|
||||
*
|
||||
* <p>
|
||||
* typedef union tdDEVICE_SECURITY_EVENT_DATA_SUB_HEADER_SPDM_CERT_CHAIN {
|
||||
* UINT16 SpdmVersion;
|
||||
* UINT8 SpdmSlotId;
|
||||
* UINT8 Reserved;
|
||||
* UINT32 SpdmBaseHashAlgo;
|
||||
* SPDM_CERT_CHAIN SpdmCertChain;
|
||||
* } DEVICE_SECURITY_EVENT_DATA_SUB_HEADER_SPDM_CERT_CHAIN;
|
||||
* <p>
|
||||
* SpdmVersion: SpdmBaseHashAlgo
|
||||
* SpdmSlotId: SlotId associated with this SPDM Certificate Chain
|
||||
* SpdmBaseHashAlgo: SPDM Base Hash Algorithm for the root certificate in the SPDM Certificate chain
|
||||
* SpdmCertChain: SPDM Certificate Chain
|
||||
*/
|
||||
public class DeviceSecurityEventDataSubHeaderCertChain extends DeviceSecurityEventDataSubHeader {
|
||||
|
||||
/**
|
||||
* SPDM version.
|
||||
*/
|
||||
private int spdmVersion = 0;
|
||||
/**
|
||||
* SPDM slot ID.
|
||||
*/
|
||||
private int spdmSlotId = 0;
|
||||
/**
|
||||
* SPDM base hash algorithm.
|
||||
*/
|
||||
private int spdmBaseHashAlgo = -1;
|
||||
/**
|
||||
* SPDM cert chain.
|
||||
*/
|
||||
private SpdmCertificateChain spdmCertChain = null;
|
||||
/**
|
||||
* Human-readable description of any error associated with SPDM base hash alg.
|
||||
*/
|
||||
private String spdmCertChainError = "";
|
||||
|
||||
/**
|
||||
* DeviceSecurityEventDataSubHeaderCertChain Constructor.
|
||||
*
|
||||
* @param dsedSubHBytes byte array holding the DeviceSecurityEventDataSubHeaderSpdmMeasurementBlock.
|
||||
*/
|
||||
public DeviceSecurityEventDataSubHeaderCertChain(final byte[] dsedSubHBytes) {
|
||||
|
||||
byte[] spdmVersionBytes = new byte[2];
|
||||
System.arraycopy(dsedSubHBytes, 0, spdmVersionBytes, 0, 2);
|
||||
spdmVersion = HexUtils.leReverseInt(spdmVersionBytes);
|
||||
|
||||
byte[] spdmLotIdBytes = new byte[1];
|
||||
System.arraycopy(dsedSubHBytes, 2, spdmLotIdBytes, 0, 1);
|
||||
spdmSlotId = HexUtils.leReverseInt(spdmLotIdBytes);
|
||||
|
||||
// byte[] reserved[Bytes]: 1 byte
|
||||
|
||||
byte[] spdmBaseHashAlgoBytes = new byte[4];
|
||||
System.arraycopy(dsedSubHBytes, 4, spdmBaseHashAlgoBytes, 0, 4);
|
||||
spdmBaseHashAlgo = HexUtils.leReverseInt(spdmBaseHashAlgoBytes);
|
||||
|
||||
// get the size of the SPDM Cert Chain
|
||||
int spdmCertChainSize = dsedSubHBytes.length - 8;
|
||||
|
||||
// extract the bytes that comprise the SPDM Cert Chain
|
||||
byte[] spdmCertChainBytes = new byte[spdmCertChainSize];
|
||||
System.arraycopy(dsedSubHBytes, 8, spdmCertChainBytes, 0,
|
||||
spdmCertChainSize);
|
||||
|
||||
int spdmBaseHashAlgoSize = SpdmHa.tcgAlgIdToByteSize(spdmBaseHashAlgo);
|
||||
|
||||
if (spdmCertChainSize <= 0) {
|
||||
spdmCertChainError += "SPDM cert chain length is not >0, "
|
||||
+ "stopping cert chain processing";
|
||||
} else if (spdmBaseHashAlgoSize <= 0) {
|
||||
spdmCertChainError += "SPDM base hash algorithm size is not >0 "
|
||||
+ "stopping cert chain processing";
|
||||
}
|
||||
if (spdmCertChainError.isEmpty()) {
|
||||
spdmCertChain = new SpdmCertificateChain(spdmCertChainBytes, spdmBaseHashAlgoSize);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a human-readable description of the data within this structure.
|
||||
*
|
||||
* @return a description of this structure.
|
||||
*/
|
||||
public String toString() {
|
||||
String dsedSubHeaderInfo = "";
|
||||
dsedSubHeaderInfo += " SPDM Version = " + spdmVersion + "\n";
|
||||
dsedSubHeaderInfo += " SPDM Slot ID = " + spdmSlotId + "\n";
|
||||
String spdmBaseHashAlgoStr = SpdmHa.tcgAlgIdToString(spdmBaseHashAlgo);
|
||||
dsedSubHeaderInfo += " SPDM Base Hash Algorithm = " + spdmBaseHashAlgoStr + "\n";
|
||||
|
||||
// SPDM Certificate Chain output
|
||||
if (!spdmCertChainError.isEmpty()) {
|
||||
dsedSubHeaderInfo += " SPDM cert chain error: " + spdmCertChainError + "\n";
|
||||
} else if (spdmCertChain == null) {
|
||||
dsedSubHeaderInfo += " SPDM cert chain error: Could not parse cert chain\n";
|
||||
} else {
|
||||
dsedSubHeaderInfo += spdmCertChain.toString();
|
||||
}
|
||||
|
||||
return dsedSubHeaderInfo;
|
||||
}
|
||||
}
|
@ -22,6 +22,14 @@ import java.util.List;
|
||||
* SPDM_MEASUREMENT_BLOCK SpdmMeasurementBlock[SpdmMeasurementBlockCount];
|
||||
* } DEVICE_SECURITY_EVENT_DATA_SUB_HEADER_SPDM_MEASUREMENT_BLOCK;
|
||||
* <p>
|
||||
*
|
||||
* SpdmMeasurementBlock is an array of SPDM_MEASUREMENT_BLOCKs
|
||||
* The size of each block is the same and can be found by either:
|
||||
* 1) 4 + SpdmMeasurementBlock MeasurementSize
|
||||
* OR
|
||||
* 2) 4 + hash length of the hash algorithm found in
|
||||
* DEVICE_SECURITY_EVENT_DATA_SUB_HEADER_SPDM_MEASUREMENT_BLOCK SpdmMeasurementHashAlgo
|
||||
* where 4 is the size of the SpdmMeasurementBlock header
|
||||
*/
|
||||
public class DeviceSecurityEventDataSubHeaderSpdmMeasurementBlock extends DeviceSecurityEventDataSubHeader {
|
||||
|
||||
@ -45,9 +53,13 @@ public class DeviceSecurityEventDataSubHeaderSpdmMeasurementBlock extends Device
|
||||
* List of SPDM Measurement Blocks.
|
||||
*/
|
||||
private List<SpdmMeasurementBlock> spdmMeasurementBlockList;
|
||||
/**
|
||||
* Error reading SPDM Measurement Block.
|
||||
*/
|
||||
private boolean spdmMeasurementBlockReadError = false;
|
||||
|
||||
/**
|
||||
* DeviceSecurityEventDataHeader Constructor.
|
||||
* DeviceSecurityEventDataSubHeaderSpdmMeasurementBlock Constructor.
|
||||
*
|
||||
* @param dsedSubHBytes byte array holding the DeviceSecurityEventDataSubHeaderSpdmMeasurementBlock.
|
||||
*/
|
||||
@ -69,7 +81,7 @@ public class DeviceSecurityEventDataSubHeaderSpdmMeasurementBlock extends Device
|
||||
System.arraycopy(dsedSubHBytes, 4, spdmMeasurementHashAlgoBytes, 0, 4);
|
||||
spdmMeasurementHashAlgo = HexUtils.leReverseInt(spdmMeasurementHashAlgoBytes);
|
||||
|
||||
// get the size of the SPDM Measurement Block List
|
||||
// get the total size of the SPDM Measurement Block List
|
||||
int spdmMeasurementBlockListSize = dsedSubHBytes.length - 8;
|
||||
|
||||
// extract the bytes that comprise the SPDM Measurement Block List
|
||||
@ -80,9 +92,14 @@ public class DeviceSecurityEventDataSubHeaderSpdmMeasurementBlock extends Device
|
||||
ByteArrayInputStream spdmMeasurementBlockListData =
|
||||
new ByteArrayInputStream(spdmMeasurementBlockListBytes);
|
||||
while (spdmMeasurementBlockListData.available() > 0) {
|
||||
SpdmMeasurementBlock spdmMeasurementBlock;
|
||||
spdmMeasurementBlock = new SpdmMeasurementBlock(spdmMeasurementBlockListData);
|
||||
spdmMeasurementBlockList.add(spdmMeasurementBlock);
|
||||
try {
|
||||
SpdmMeasurementBlock spdmMeasurementBlock =
|
||||
new SpdmMeasurementBlock(spdmMeasurementBlockListData);
|
||||
spdmMeasurementBlockList.add(spdmMeasurementBlock);
|
||||
} catch (IOException e) {
|
||||
spdmMeasurementBlockReadError = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -93,18 +110,23 @@ public class DeviceSecurityEventDataSubHeaderSpdmMeasurementBlock extends Device
|
||||
*/
|
||||
public String toString() {
|
||||
String dsedSubHeaderInfo = "";
|
||||
dsedSubHeaderInfo += "\n SPDM Version: " + spdmVersion;
|
||||
dsedSubHeaderInfo += " SPDM Version = " + spdmVersion + "\n";
|
||||
String spdmHashAlgoStr = SpdmHa.tcgAlgIdToString(spdmMeasurementHashAlgo);
|
||||
dsedSubHeaderInfo += "\n SPDM Hash Algorithm = " + spdmHashAlgoStr;
|
||||
dsedSubHeaderInfo += " SPDM Hash Algorithm = " + spdmHashAlgoStr + "\n";
|
||||
|
||||
// SPDM Measurement Block List output
|
||||
dsedSubHeaderInfo += "\n Number of SPDM Measurement Blocks = " + spdmMeasurementBlockList.size();
|
||||
dsedSubHeaderInfo += " Number of SPDM Measurement Blocks = "
|
||||
+ spdmMeasurementBlockList.size() + "\n";
|
||||
int spdmMeasBlockCnt = 1;
|
||||
for (SpdmMeasurementBlock spdmMeasBlock : spdmMeasurementBlockList) {
|
||||
dsedSubHeaderInfo += "\n SPDM Measurement Block # " + spdmMeasBlockCnt++ + " of " +
|
||||
spdmMeasurementBlockList.size();
|
||||
dsedSubHeaderInfo += " SPDM Measurement Block # " + spdmMeasBlockCnt++ + " of "
|
||||
+ spdmMeasurementBlockList.size() + "\n";
|
||||
dsedSubHeaderInfo += spdmMeasBlock.toString();
|
||||
}
|
||||
if (spdmMeasurementBlockReadError) {
|
||||
dsedSubHeaderInfo += " Error reading SPDM Measurement Block #"
|
||||
+ spdmMeasBlockCnt + ", halting processing\n";
|
||||
}
|
||||
|
||||
return dsedSubHeaderInfo;
|
||||
}
|
||||
|
@ -5,7 +5,6 @@ import hirs.utils.tpm.eventlog.uefi.UefiConstants;
|
||||
import hirs.utils.tpm.eventlog.uefi.UefiDevicePath;
|
||||
import lombok.Getter;
|
||||
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
/**
|
||||
@ -64,8 +63,8 @@ public abstract class DeviceSecurityEventHeader {
|
||||
@Getter
|
||||
private String signature = "";
|
||||
/**
|
||||
* Version determines data structure used (..DATA or ..DATA2),
|
||||
* which determines whether ..HEADER or ..HEADER2 is used
|
||||
* Version determines data structure used (..DATA or ..DATA2).
|
||||
* This determines whether ..HEADER or ..HEADER2 is used.
|
||||
*/
|
||||
@Getter
|
||||
private String version = "";
|
||||
@ -84,34 +83,9 @@ public abstract class DeviceSecurityEventHeader {
|
||||
*/
|
||||
@Getter
|
||||
private UefiDevicePath devicePath = null;
|
||||
/**
|
||||
* Is the Device Path Valid.
|
||||
*/
|
||||
private boolean devicePathValid = false;
|
||||
|
||||
/**
|
||||
* Device Security Event Data Device Type = no device type.
|
||||
*/
|
||||
public static final int DEVICE_TYPE_NONE = 0;
|
||||
/**
|
||||
* Device Security Event Data Device Type = DEVICE_TYPE_PCI.
|
||||
*/
|
||||
public static final int DEVICE_TYPE_PCI = 1;
|
||||
/**
|
||||
* Device Security Event Data Device Type = DEVICE_TYPE_USB.
|
||||
*/
|
||||
public static final int DEVICE_TYPE_USB = 2;
|
||||
|
||||
|
||||
/**
|
||||
* DeviceSecurityEventDataHeaderBase Default Constructor.
|
||||
*/
|
||||
public DeviceSecurityEventHeader() {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* DeviceSecurityEventDataHeaderBase Constructor.
|
||||
* DeviceSecurityEventDataHeader Constructor.
|
||||
*
|
||||
* @param dSEDbytes byte array holding the DeviceSecurityEventData.
|
||||
*/
|
||||
@ -126,7 +100,6 @@ public abstract class DeviceSecurityEventHeader {
|
||||
System.arraycopy(dSEDbytes, UefiConstants.OFFSET_16, versionBytes, 0,
|
||||
UefiConstants.SIZE_2);
|
||||
version = HexUtils.byteArrayToHexString(versionBytes);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@ -135,7 +108,7 @@ public abstract class DeviceSecurityEventHeader {
|
||||
* @param dsedBytes byte array holding the DeviceSecurityEventData/Data2.
|
||||
* @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, final int startByte) {
|
||||
|
||||
// get the device type ID
|
||||
byte[] deviceTypeBytes = new byte[UefiConstants.SIZE_4];
|
||||
@ -151,31 +124,26 @@ public abstract class DeviceSecurityEventHeader {
|
||||
* @param dsedBytes byte array holding the DeviceSecurityEventData/Data2.
|
||||
* @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, final int startByte) {
|
||||
|
||||
int startByteUpdated = startByte;
|
||||
|
||||
// get the device path length
|
||||
byte[] devicePathLengthBytes = new byte[UefiConstants.SIZE_8];
|
||||
System.arraycopy(dsedBytes, startByte, devicePathLengthBytes, 0,
|
||||
UefiConstants.SIZE_8);
|
||||
byte[] devicePathLengthBytes = new byte[8];
|
||||
System.arraycopy(dsedBytes, startByteUpdated, devicePathLengthBytes, 0, 8);
|
||||
int devicePathLength = HexUtils.leReverseInt(devicePathLengthBytes);
|
||||
|
||||
// get the device path
|
||||
if (devicePathLength != 0) {
|
||||
startByte = startByte + UefiConstants.SIZE_8;
|
||||
if (devicePathLength > 0) {
|
||||
startByteUpdated = startByteUpdated + 8;
|
||||
byte[] devPathBytes = new byte[devicePathLength];
|
||||
System.arraycopy(dsedBytes, startByte, devPathBytes,
|
||||
System.arraycopy(dsedBytes, startByteUpdated, devPathBytes,
|
||||
0, devicePathLength);
|
||||
try {
|
||||
devicePath = new UefiDevicePath(devPathBytes);
|
||||
devicePathValid = true;
|
||||
}
|
||||
catch (UnsupportedEncodingException e) {
|
||||
devicePathValid = false;
|
||||
}
|
||||
devicePath = new UefiDevicePath(devPathBytes);
|
||||
}
|
||||
|
||||
// header total size
|
||||
dsedHeaderLength = startByte + devicePathLength;
|
||||
dsedHeaderLength = startByteUpdated + devicePathLength;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -187,11 +155,11 @@ public abstract class DeviceSecurityEventHeader {
|
||||
*/
|
||||
public String deviceTypeToString(final int deviceTypeInt) {
|
||||
switch (deviceTypeInt) {
|
||||
case DEVICE_TYPE_NONE:
|
||||
case DeviceSecurityEventDataDeviceContext.DEVICE_TYPE_NONE:
|
||||
return "No device type";
|
||||
case DEVICE_TYPE_PCI:
|
||||
case DeviceSecurityEventDataDeviceContext.DEVICE_TYPE_PCI:
|
||||
return "PCI";
|
||||
case DEVICE_TYPE_USB:
|
||||
case DeviceSecurityEventDataDeviceContext.DEVICE_TYPE_USB:
|
||||
return "USB";
|
||||
default:
|
||||
return "Unknown or invalid Device Type";
|
||||
@ -206,13 +174,12 @@ public abstract class DeviceSecurityEventHeader {
|
||||
public String toString() {
|
||||
String dsedHeaderCommonInfo = "";
|
||||
|
||||
dsedHeaderCommonInfo += "\n SPDM Device Type = " + deviceTypeToString(deviceType);
|
||||
if (devicePathValid) {
|
||||
dsedHeaderCommonInfo += "\n SPDM Device Path:\n";
|
||||
dsedHeaderCommonInfo += " SPDM Device Type = " + deviceTypeToString(deviceType) + "\n";
|
||||
if (devicePath != null) {
|
||||
dsedHeaderCommonInfo += " SPDM Device Path:\n";
|
||||
dsedHeaderCommonInfo += devicePath;
|
||||
}
|
||||
else {
|
||||
dsedHeaderCommonInfo += "\n SPDM Device Path = Unknown or invalid";
|
||||
} else {
|
||||
dsedHeaderCommonInfo += " SPDM Device Path = Unknown or invalid\n";
|
||||
}
|
||||
|
||||
return dsedHeaderCommonInfo;
|
||||
|
@ -117,15 +117,15 @@ public class EvEfiBootServicesApp {
|
||||
* @return a human readable string.
|
||||
*/
|
||||
public String toString() {
|
||||
String info = "Image info: ";
|
||||
info += " Image physical address: " + HexUtils.byteArrayToHexString(physicalAddress);
|
||||
info += " Image length = " + imageLength;
|
||||
info += " Image link time address: " + HexUtils.byteArrayToHexString(physicalAddress);
|
||||
info += " Device path length = " + devicePathLength;
|
||||
String info = " Image info:\n";
|
||||
info += " Image physical address = " + HexUtils.byteArrayToHexString(physicalAddress) + "\n";
|
||||
info += " Image length = " + imageLength + "\n";
|
||||
info += " Image link time address = " + HexUtils.byteArrayToHexString(physicalAddress) + "\n";
|
||||
info += " Device path length = " + devicePathLength + "\n";
|
||||
if (devicePathValid) {
|
||||
info += "\n" + devicePath.toString();
|
||||
info += devicePath.toString() + "\n";
|
||||
} else {
|
||||
info += "\n No uefi device paths were specified";
|
||||
info += " No uefi device paths were specified\n";
|
||||
}
|
||||
return info;
|
||||
}
|
||||
|
@ -128,14 +128,15 @@ public class EvEfiHandoffTable {
|
||||
*/
|
||||
public String toString() {
|
||||
StringBuilder tableInfo = new StringBuilder();
|
||||
tableInfo.append("Number of UEFI_CONFIGURATION_TABLEs = " + numberOfTables + "\n");
|
||||
tableInfo.append(" Number of UEFI_CONFIGURATION_TABLEs = " + numberOfTables + "\n");
|
||||
for (int i = 0; i < numberOfTables; i++) {
|
||||
UefiGuid currentGuid = vendorGuids.get(i);
|
||||
tableInfo.append(" Table " + i + ": " + currentGuid.toString());
|
||||
tableInfo.append(" UEFI industry standard table type = "
|
||||
tableInfo.append(" Table " + i + ":\n");
|
||||
tableInfo.append(" GUID = " + currentGuid.toString() + "\n");
|
||||
tableInfo.append(" UEFI industry standard table type = "
|
||||
+ currentGuid.getVendorTableReference() + "\n");
|
||||
tableInfo.append(" VendorTable " + i + " address: "
|
||||
+ HexUtils.byteArrayToHexString(vendorTables.get(i)));
|
||||
tableInfo.append(" VendorTable " + i + " address: "
|
||||
+ HexUtils.byteArrayToHexString(vendorTables.get(i)) + "\n");
|
||||
}
|
||||
return tableInfo.toString();
|
||||
}
|
||||
|
@ -2,10 +2,7 @@ package hirs.utils.tpm.eventlog.events;
|
||||
|
||||
import hirs.utils.HexUtils;
|
||||
import hirs.utils.tpm.eventlog.uefi.UefiConstants;
|
||||
import lombok.Getter;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
/**
|
||||
@ -41,60 +38,55 @@ 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 = "";
|
||||
private String spdmInfo = "";
|
||||
|
||||
/**
|
||||
* 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";
|
||||
spdmInfo = " Signature = SPDM Device Sec2\n";
|
||||
|
||||
if (version.equals("0200")) {
|
||||
if (dsedVersion.equals("0200")) {
|
||||
dsed = new DeviceSecurityEventData2(eventData);
|
||||
spdmInfo += dsed.toString();
|
||||
} else {
|
||||
spdmInfo += " Incompatible version for DeviceSecurityEventData2: " + dsedVersion + "\n";
|
||||
}
|
||||
else {
|
||||
spdmInfo += " Incompatible version for DeviceSecurityEventData2: " + version;
|
||||
}
|
||||
}
|
||||
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";
|
||||
spdmInfo = " Signature = SPDM Device Sec\n";
|
||||
|
||||
if (version.equals("0100")) {
|
||||
if (dsedVersion.equals("0100")) {
|
||||
dsed = new DeviceSecurityEventData(eventData);
|
||||
spdmInfo += dsed.toString();
|
||||
} else {
|
||||
spdmInfo += " Incompatible version for DeviceSecurityEventData: " + dsedVersion + "\n";
|
||||
}
|
||||
else {
|
||||
spdmInfo += " Incompatible version for DeviceSecurityEventData: " + version;
|
||||
}
|
||||
}
|
||||
else {
|
||||
spdmInfo = " Signature = Undetermined value: " + signature;
|
||||
} else {
|
||||
spdmInfo = " Signature = Undetermined value: " + dsedSignature + "\n";
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -98,7 +98,6 @@ public class EvEfiSpecIdEvent {
|
||||
algList = new ArrayList<>();
|
||||
byte[] signatureBytes = new byte[UefiConstants.SIZE_16];
|
||||
System.arraycopy(efiSpecId, 0, signatureBytes, 0, UefiConstants.SIZE_16);
|
||||
signature = HexUtils.byteArrayToHexString(signatureBytes);
|
||||
signature = new String(signatureBytes, StandardCharsets.UTF_8)
|
||||
.substring(0, UefiConstants.SIZE_15);
|
||||
|
||||
|
@ -1,5 +1,6 @@
|
||||
package hirs.utils.tpm.eventlog.events;
|
||||
|
||||
import hirs.utils.HexUtils;
|
||||
import hirs.utils.tpm.eventlog.uefi.UefiConstants;
|
||||
import lombok.Getter;
|
||||
|
||||
@ -7,12 +8,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
|
||||
@ -29,10 +33,21 @@ public class EvNoAction {
|
||||
*/
|
||||
private boolean bSpecIDEvent = false;
|
||||
/**
|
||||
* EvEfiSpecIdEvent Object.
|
||||
* TCG Event Log spec version.
|
||||
*/
|
||||
@Getter
|
||||
private EvEfiSpecIdEvent specIDEvent = null;
|
||||
private String specVersion = "Unknown";
|
||||
/**
|
||||
* TCG Event Log errata version.
|
||||
*/
|
||||
@Getter
|
||||
private String specErrataVersion = "Unknown";
|
||||
|
||||
/**
|
||||
* Human-readable description of the data within this DEVICE_SECURITY_EVENT_DATA/..DATA2 event.
|
||||
*/
|
||||
@Getter
|
||||
private String noActionInfo = "";
|
||||
|
||||
/**
|
||||
* EvNoAction constructor.
|
||||
@ -46,8 +61,23 @@ public class EvNoAction {
|
||||
signature = new String(signatureBytes, StandardCharsets.UTF_8);
|
||||
signature = signature.replaceAll("[^\\P{C}\t\r\n]", ""); // remove null characters
|
||||
if (signature.contains("Spec ID Event03")) { // implies CryptAgileFormat
|
||||
specIDEvent = new EvEfiSpecIdEvent(eventData);
|
||||
EvEfiSpecIdEvent specIDEvent = new EvEfiSpecIdEvent(eventData);
|
||||
noActionInfo += specIDEventToString(specIDEvent).toString();
|
||||
bSpecIDEvent = true;
|
||||
specVersion = String.format("%s.%s",
|
||||
specIDEvent.getVersionMajor(),
|
||||
specIDEvent.getVersionMinor());
|
||||
specErrataVersion = specIDEvent.getErrata();
|
||||
} else if (signature.contains("StartupLocality")) {
|
||||
noActionInfo += " Signature = StartupLocality";
|
||||
noActionInfo += "\n StartupLocality = " + getLocality(eventData);
|
||||
} else if (signature.contains("NvIndexInstance")) {
|
||||
NvIndexInstanceEventLogData nvIndexInstanceEvent = new NvIndexInstanceEventLogData(eventData);
|
||||
noActionInfo += nvIndexInstanceEvent.toString();
|
||||
} else {
|
||||
noActionInfo = "EV_NO_ACTION event named " + signature
|
||||
+ " encountered but support for processing it has not been"
|
||||
+ " added to this application.\n";
|
||||
}
|
||||
}
|
||||
|
||||
@ -60,27 +90,62 @@ public class EvNoAction {
|
||||
return bSpecIDEvent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a human-readable description of a SpecId event.
|
||||
*
|
||||
* @param specIDEvent byte array holding the event.
|
||||
* @return a description of the event.
|
||||
*/
|
||||
public String specIDEventToString(final EvEfiSpecIdEvent specIDEvent) {
|
||||
|
||||
String specIdInfo = "";
|
||||
specIdInfo += " Signature = Spec ID Event03 : ";
|
||||
if (specIDEvent.isCryptoAgile()) {
|
||||
specIdInfo += "Log format is Crypto Agile\n";
|
||||
} else {
|
||||
specIdInfo += "Log format is SHA 1 (NOT Crypto Agile)\n";
|
||||
}
|
||||
specIdInfo += " Platform Profile Specification version = "
|
||||
+ specIDEvent.getVersionMajor() + "." + specIDEvent.getVersionMinor()
|
||||
+ " using errata version " + specIDEvent.getErrata();
|
||||
|
||||
return specIdInfo;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a human-readable description of locality based on numeric representation lookup.
|
||||
*
|
||||
* @param eventData byte array holding the event from which to grab locality
|
||||
* @return a description of the locality.
|
||||
*/
|
||||
private String getLocality(final byte[] eventData) {
|
||||
String localityInfo = "";
|
||||
byte[] localityBytes = new byte[1];
|
||||
System.arraycopy(eventData, 16, localityBytes, 0, 1);
|
||||
int locality = HexUtils.leReverseInt(localityBytes);
|
||||
|
||||
switch (locality) {
|
||||
case 0:
|
||||
localityInfo += "Locality 0 without an H-CRTM sequence";
|
||||
break;
|
||||
case 3:
|
||||
localityInfo += "Locality 3 without an H-CRTM sequence";
|
||||
break;
|
||||
case 4:
|
||||
localityInfo += "Locality 4 with an H-CRTM sequence initialized";
|
||||
break;
|
||||
default:
|
||||
localityInfo += "Unknown";
|
||||
}
|
||||
return localityInfo;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a description of this event.
|
||||
*
|
||||
* @return Human readable description of this event.
|
||||
* @return Human-readable description of this event.
|
||||
*/
|
||||
public String toString() {
|
||||
String specInfo = "";
|
||||
if (bSpecIDEvent) {
|
||||
specInfo += " Signature = Spec ID Event03 : ";
|
||||
if (specIDEvent.isCryptoAgile()) {
|
||||
specInfo += "Log format is Crypto Agile\n";
|
||||
} else {
|
||||
specInfo += "Log format is SHA 1 (NOT Crypto Agile)\n";
|
||||
}
|
||||
specInfo += " Platform Profile Specification version = "
|
||||
+ specIDEvent.getVersionMajor() + "." + specIDEvent.getVersionMinor()
|
||||
+ " using errata version " + specIDEvent.getErrata();
|
||||
} else {
|
||||
specInfo = "EV_NO_ACTION event named " + signature
|
||||
+ " encountered but support for processing it has not been added to this application.\n";
|
||||
}
|
||||
return specInfo;
|
||||
return noActionInfo;
|
||||
}
|
||||
}
|
||||
|
@ -39,14 +39,14 @@ public class EvSCrtmVersion {
|
||||
if (UefiGuid.isValidUUID(data)) {
|
||||
guid = new UefiGuid(data);
|
||||
String guidInfo = guid.toStringNoLookup();
|
||||
description = " SCRM Version = " + guidInfo;
|
||||
description = " SCRM Version = " + guidInfo;
|
||||
}
|
||||
} else if (data.length < UefiConstants.SIZE_4) {
|
||||
description = HexUtils.byteArrayToHexString(data);
|
||||
} else if (EvPostCode.isAscii(data)) {
|
||||
description = new String(data, StandardCharsets.UTF_8);
|
||||
} else {
|
||||
description = "Unknown Version format";
|
||||
description = " Unknown Version format";
|
||||
}
|
||||
}
|
||||
return (description);
|
||||
|
@ -0,0 +1,105 @@
|
||||
package hirs.utils.tpm.eventlog.events;
|
||||
|
||||
import hirs.utils.HexUtils;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
/**
|
||||
* Class to process the NV_INDEX_INSTANCE_EVENT_LOG_DATA per PFP.
|
||||
* 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 tdNV_INDEX_INSTANCE_EVENT_LOG_DATA {
|
||||
* BYTE Signature[16];
|
||||
* UINT16 Version;
|
||||
* 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 = "";
|
||||
|
||||
/**
|
||||
* Human-readable description of the data within this DEVICE_SECURITY_EVENT_DATA/..DATA2 event.
|
||||
*/
|
||||
private 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 nvIndexVersion = HexUtils.byteArrayToHexString(versionBytes);
|
||||
if (nvIndexVersion == "") {
|
||||
nvIndexVersion = "version not readable";
|
||||
}
|
||||
nvIndexInstanceInfo = " Nv Index Instance Signature = " + signature + "\n";
|
||||
nvIndexInstanceInfo += " Nv Index Instance Version = " + nvIndexVersion + "\n";
|
||||
|
||||
// 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\n";
|
||||
|
||||
if (dsedVersion.equals("0200")) {
|
||||
dsed = new DeviceSecurityEventData2(dsedEventData);
|
||||
nvIndexInstanceInfo += dsed.toString();
|
||||
} else {
|
||||
nvIndexInstanceInfo += " Incompatible version for DeviceSecurityEventData2: "
|
||||
+ dsedVersion + "\n";
|
||||
}
|
||||
} else {
|
||||
nvIndexInstanceInfo = " Signature error: should be \'SPDM Device Sec2\' but is "
|
||||
+ signature + "\n";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a description of this event.
|
||||
*
|
||||
* @return Human-readable description of this event.
|
||||
*/
|
||||
public String toString() {
|
||||
return nvIndexInstanceInfo;
|
||||
}
|
||||
}
|
@ -0,0 +1,172 @@
|
||||
package hirs.utils.tpm.eventlog.spdm;
|
||||
|
||||
import hirs.utils.HexUtils;
|
||||
import hirs.utils.tpm.eventlog.uefi.UefiX509Cert;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
import java.math.BigInteger;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.cert.CertificateException;
|
||||
import java.util.ArrayList;
|
||||
|
||||
/**
|
||||
* Class to process the SpdmCertificateChain.
|
||||
* <p>
|
||||
* Certificate chain format, defined by SPDM v1.03, Sect 10.6.1, Table 33:
|
||||
* Certificate chain format {
|
||||
* Length 2 bytes;
|
||||
* Reserved 2 bytes;
|
||||
* RootHash <H> bytes;
|
||||
* Certificates <Length> - (4 + <H>) bytes;
|
||||
* }
|
||||
* <p>
|
||||
* Length: total length of cert chain including all fields in this block
|
||||
* H: the output size of the hash algorithm selected by the most recent ALGORITHMS response
|
||||
* this field shall be in hash byte order
|
||||
* hash algorithm is included in the DEVICE_SECURITY_EVENT_DATA_SUB_HEADER_SPDM_CERT_CHAIN
|
||||
* structure as the member "SpdmBaseHashAlg"
|
||||
* RootHash: the digest of the Root Certificate.
|
||||
* size is determined by hash algorithm selected by the most recent SPDM ALGORITHMS response;
|
||||
* the hash algorithm is the DEVICE_SECURITY_EVENT_DATA_SUB_HEADER_SPDM_CERT_CHAIN SpdmBaseHashAlgo
|
||||
* Certificates: Complete cert chain consisting of 1 or more ASN.1 DER-encoded X.509 v3 certs
|
||||
* this field shall be in Encoded ASN.1 byte order
|
||||
*/
|
||||
public class SpdmCertificateChain {
|
||||
|
||||
///**
|
||||
// * Length of the certificate chain to include all fields in this structure.
|
||||
// */
|
||||
//private int length = 0;
|
||||
/**
|
||||
* Root hash.
|
||||
*/
|
||||
private byte[] rootHash = null;
|
||||
/**
|
||||
* Number of certs in the SPDM cert chain.
|
||||
*/
|
||||
private int numberOfCerts = 0;
|
||||
/**
|
||||
* Array List of certs found in the chain.
|
||||
*/
|
||||
private ArrayList<UefiX509Cert> certList = new ArrayList<UefiX509Cert>();
|
||||
/**
|
||||
* Human-readable description of any error associated with SPDM base hash alg.
|
||||
*/
|
||||
private String spdmBaseHashAlgoError = "";
|
||||
/**
|
||||
* Human-readable description of any error associated with parsing the X509 certs.
|
||||
*/
|
||||
private String certProcessingError = "";
|
||||
|
||||
/**
|
||||
* SpdmCertificateChain Constructor.
|
||||
*
|
||||
* @param spdmCertChainBytes byte array holding the SPDM Cert Chain bytes.
|
||||
* @param rootHashLength length of RootHash.
|
||||
*/
|
||||
public SpdmCertificateChain(final byte[] spdmCertChainBytes, final int rootHashLength) {
|
||||
|
||||
if (rootHashLength <= 0) {
|
||||
spdmBaseHashAlgoError = "SPDM base hash algorithm size is not >0";
|
||||
} else {
|
||||
byte[] lengthBytes = new byte[2];
|
||||
System.arraycopy(spdmCertChainBytes, 0, lengthBytes, 0, 2);
|
||||
//length = HexUtils.leReverseInt(lengthBytes);
|
||||
|
||||
// Reserved: 2 bytes
|
||||
|
||||
rootHash = new byte[rootHashLength];
|
||||
System.arraycopy(spdmCertChainBytes, 4, rootHash, 0, rootHashLength);
|
||||
|
||||
int certChainStartPos = 4 + rootHashLength;
|
||||
int certChainLength = spdmCertChainBytes.length - certChainStartPos;
|
||||
byte[] certChainBytes = new byte[certChainLength];
|
||||
System.arraycopy(spdmCertChainBytes, certChainStartPos, certChainBytes, 0, certChainLength);
|
||||
|
||||
processCertChain(certChainBytes);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Method for processing the data in an EFI SignatureList (ex. can be one or more X509 certs)
|
||||
*
|
||||
* @param certChainData Byte array holding the cert chain data
|
||||
*/
|
||||
private void processCertChain(final byte[] certChainData) {
|
||||
|
||||
UefiX509Cert cert = null;
|
||||
|
||||
ByteArrayInputStream certChainDataIS = new ByteArrayInputStream(certChainData);
|
||||
while (certChainDataIS.available() > 0) {
|
||||
|
||||
// java.io.IOException If there's a problem parsing the cert chain data.
|
||||
// java.security.cert.CertificateException if there's a problem parsing the X509 certificate.
|
||||
// java.security.NoSuchAlgorithmException if there's a problem hashing the certificate.
|
||||
try {
|
||||
byte[] certType = new byte[2];
|
||||
certChainDataIS.read(certType);
|
||||
byte[] certLength = new byte[2];
|
||||
certChainDataIS.read(certLength);
|
||||
//int cLength = new BigInteger(certLength).intValue() + UefiConstants.SIZE_4;
|
||||
int cLength = new BigInteger(certLength).intValue();
|
||||
byte[] certData = new byte[cLength];
|
||||
certChainDataIS.read(certData);
|
||||
// put the cert back together
|
||||
byte[] certBlob = new byte[cLength + 4];
|
||||
System.arraycopy(certType, 0, certBlob, 0, 2);
|
||||
System.arraycopy(certLength, 0, certBlob, 2, 2);
|
||||
System.arraycopy(certData, 0, certBlob, 4, cLength);
|
||||
cert = new UefiX509Cert(certBlob);
|
||||
//cert = new X509Certificate(certBlob);
|
||||
certList.add(cert);
|
||||
numberOfCerts++;
|
||||
} catch (IOException e) {
|
||||
certProcessingError += "Error with Cert # " + (numberOfCerts + 1)
|
||||
+ ": IOException (error reading cert data)";
|
||||
break;
|
||||
} catch (CertificateException e) {
|
||||
certProcessingError += "Error with Cert # " + (numberOfCerts + 1)
|
||||
+ ": CertificateException";
|
||||
break;
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
certProcessingError += "Error with Cert # " + (numberOfCerts + 1)
|
||||
+ ": CNoSuchAlgorithmException";
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a human-readable description of the data within this structure.
|
||||
*
|
||||
* @return a description of this structure.
|
||||
*/
|
||||
public String toString() {
|
||||
|
||||
String spdmCertChainInfo = "";
|
||||
|
||||
if (!spdmBaseHashAlgoError.isEmpty()) {
|
||||
spdmCertChainInfo += " *** ERROR with SPDM base hash algorithm size ***\n";
|
||||
spdmCertChainInfo += " " + spdmBaseHashAlgoError + "\n";
|
||||
spdmCertChainInfo += " Stopping processing of this cert chain\n";
|
||||
} else {
|
||||
spdmCertChainInfo += " Root hash = " + HexUtils.byteArrayToHexString(rootHash) + "\n";
|
||||
spdmCertChainInfo += " Number of certs in chain = " + numberOfCerts + "\n";
|
||||
|
||||
int certCnt = 1;
|
||||
for (UefiX509Cert cert : certList) {
|
||||
spdmCertChainInfo += " Cert # " + certCnt++ + " of "
|
||||
+ numberOfCerts + ": ------------------\n";
|
||||
spdmCertChainInfo += cert.toString();
|
||||
}
|
||||
|
||||
if (!certProcessingError.isEmpty()) {
|
||||
spdmCertChainInfo += " *** ERROR processing cert ***\n";
|
||||
spdmCertChainInfo += " " + certProcessingError + "\n";
|
||||
spdmCertChainInfo += " Stopping processing of this cert chain\n";
|
||||
}
|
||||
}
|
||||
return spdmCertChainInfo;
|
||||
}
|
||||
}
|
@ -11,7 +11,7 @@ import lombok.NoArgsConstructor;
|
||||
public class SpdmHa {
|
||||
|
||||
/**
|
||||
* Spdm Hash Alg = Raw bit stream
|
||||
* Spdm Hash Alg = Raw bit stream.
|
||||
*/
|
||||
public static final int TPM_ALG_RAW = 1;
|
||||
/**
|
||||
@ -41,7 +41,7 @@ public class SpdmHa {
|
||||
|
||||
/**
|
||||
* Returns the hash name via a lookup.
|
||||
* Lookup based upon section 10.4 for the SPDM v1.03 document.
|
||||
* Lookup based upon SPDM Spec v1.03 section 10.4.
|
||||
*
|
||||
* @param algId int to convert to string
|
||||
* @return name of the algorithm
|
||||
@ -75,4 +75,41 @@ public class SpdmHa {
|
||||
}
|
||||
return alg;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the hash value size based on the hash algorithm.
|
||||
* Lookup based upon SPDM Spec v1.03 section 10.4.
|
||||
*
|
||||
* @param algId int to convert to string
|
||||
* @return size of the algorithm output
|
||||
*/
|
||||
public static int tcgAlgIdToByteSize(final int algId) {
|
||||
int byteSize;
|
||||
switch (algId) {
|
||||
//case TPM_ALG_RAW: // add this when have more test data
|
||||
// byteSize = ;
|
||||
// break;
|
||||
case TPM_ALG_SHA_256:
|
||||
byteSize = 32;
|
||||
break;
|
||||
case TPM_ALG_SHA_384:
|
||||
byteSize = 48;
|
||||
break;
|
||||
case TPM_ALG_SHA_512:
|
||||
byteSize = 64;
|
||||
break;
|
||||
case TPM_ALG_SHA3_256:
|
||||
byteSize = 32;
|
||||
break;
|
||||
case TPM_ALG_SHA3_384:
|
||||
byteSize = 48;
|
||||
break;
|
||||
case TPM_ALG_SHA3_512:
|
||||
byteSize = 64;
|
||||
break;
|
||||
default:
|
||||
byteSize = -1;
|
||||
}
|
||||
return byteSize;
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,6 @@
|
||||
package hirs.utils.tpm.eventlog.spdm;
|
||||
|
||||
import hirs.utils.HexUtils;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.Getter;
|
||||
|
||||
/**
|
||||
@ -36,7 +35,7 @@ public class SpdmMeasurement {
|
||||
/**
|
||||
* Measurement value (digest).
|
||||
*/
|
||||
private byte[] dmtfSpecMeasurementValue = null;
|
||||
private byte[] dmtfSpecMeasurementValue;
|
||||
|
||||
/**
|
||||
* SpdmMeasurement Constructor.
|
||||
@ -62,7 +61,7 @@ public class SpdmMeasurement {
|
||||
}
|
||||
|
||||
/**
|
||||
* Lookup for SPDM measurement value type
|
||||
* Lookup for SPDM measurement value type.
|
||||
*
|
||||
* @param measValType the numerical representation of the measurement value type.
|
||||
*
|
||||
@ -119,10 +118,11 @@ public class SpdmMeasurement {
|
||||
public String toString() {
|
||||
String spdmMeasInfo = "";
|
||||
|
||||
spdmMeasInfo += "\n SPDM Measurement Value Type = " +
|
||||
dmtfSpecMeasurementValueTypeToString(dmtfSpecMeasurementValueType);
|
||||
spdmMeasInfo += "\n SPDM Measurement Value = " +
|
||||
HexUtils.byteArrayToHexString(dmtfSpecMeasurementValue);
|
||||
spdmMeasInfo += " SPDM Measurement Value Type = "
|
||||
+ dmtfSpecMeasurementValueTypeToString(dmtfSpecMeasurementValueType);
|
||||
spdmMeasInfo += "\n SPDM Measurement Value = "
|
||||
+ HexUtils.byteArrayToHexString(dmtfSpecMeasurementValue);
|
||||
spdmMeasInfo += "\n";
|
||||
|
||||
return spdmMeasInfo;
|
||||
}
|
||||
|
@ -1,16 +1,10 @@
|
||||
package hirs.utils.tpm.eventlog.spdm;
|
||||
|
||||
import hirs.utils.HexUtils;
|
||||
import hirs.utils.tpm.eventlog.uefi.UefiConstants;
|
||||
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.
|
||||
@ -46,57 +40,44 @@ public class SpdmMeasurementBlock {
|
||||
* SPDM Measurement.
|
||||
*/
|
||||
private SpdmMeasurement spdmMeasurement;
|
||||
/**
|
||||
* Error reading SPDM Measurement Block.
|
||||
*/
|
||||
private boolean spdmMeasurementBlockReadError = false;
|
||||
|
||||
/**
|
||||
* SpdmMeasurementBlock Constructor.
|
||||
*
|
||||
* @param spdmMeasBlocks byte array holding the SPDM Measurement Block bytes.
|
||||
*/
|
||||
public SpdmMeasurementBlock(final ByteArrayInputStream spdmMeasBlocks) {
|
||||
public SpdmMeasurementBlock(final ByteArrayInputStream spdmMeasBlocks) throws IOException {
|
||||
|
||||
try {
|
||||
byte[] indexBytes = new byte[1];
|
||||
spdmMeasBlocks.read(indexBytes);
|
||||
index = HexUtils.leReverseInt(indexBytes);
|
||||
byte[] indexBytes = new byte[1];
|
||||
spdmMeasBlocks.read(indexBytes);
|
||||
index = HexUtils.leReverseInt(indexBytes);
|
||||
|
||||
byte[] measurementSpecBytes = new byte[1];
|
||||
spdmMeasBlocks.read(measurementSpecBytes);
|
||||
measurementSpec = HexUtils.leReverseInt(measurementSpecBytes);
|
||||
byte[] measurementSpecBytes = new byte[1];
|
||||
spdmMeasBlocks.read(measurementSpecBytes);
|
||||
measurementSpec = HexUtils.leReverseInt(measurementSpecBytes);
|
||||
|
||||
// in future, can crosscheck this measurement size with the MeasurementSpec hash alg size
|
||||
byte[] measurementSizeBytes = new byte[2];
|
||||
spdmMeasBlocks.read(measurementSizeBytes);
|
||||
int measurementSize = HexUtils.leReverseInt(measurementSizeBytes);
|
||||
// in future, can crosscheck this measurement size with the MeasurementSpec hash alg size
|
||||
byte[] measurementSizeBytes = new byte[2];
|
||||
spdmMeasBlocks.read(measurementSizeBytes);
|
||||
int measurementSize = HexUtils.leReverseInt(measurementSizeBytes);
|
||||
|
||||
byte[] measurementBytes = new byte[measurementSize];
|
||||
spdmMeasBlocks.read(measurementBytes);
|
||||
spdmMeasurement = new SpdmMeasurement(measurementBytes);
|
||||
} catch (IOException ioEx) {
|
||||
spdmMeasurementBlockReadError = true;
|
||||
}
|
||||
byte[] measurementBytes = new byte[measurementSize];
|
||||
spdmMeasBlocks.read(measurementBytes);
|
||||
spdmMeasurement = new SpdmMeasurement(measurementBytes);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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() {
|
||||
|
||||
String spdmMeasBlockInfo = "";
|
||||
|
||||
if(spdmMeasurementBlockReadError) {
|
||||
spdmMeasBlockInfo += "\n Error reading SPDM Measurement Block";
|
||||
}
|
||||
else {
|
||||
spdmMeasBlockInfo += "\n Index = " + index;
|
||||
spdmMeasBlockInfo += "\n MeasurementSpec = " + measurementSpec;
|
||||
spdmMeasBlockInfo += spdmMeasurement.toString();
|
||||
}
|
||||
spdmMeasBlockInfo += " Index = " + index + "\n";
|
||||
spdmMeasBlockInfo += " MeasurementSpec = " + measurementSpec + "\n";
|
||||
spdmMeasBlockInfo += spdmMeasurement.toString();
|
||||
|
||||
return spdmMeasBlockInfo;
|
||||
}
|
||||
|
@ -25,15 +25,15 @@ public class UefiBootOrder {
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides a human readable Boot Order list on single line.
|
||||
* Provides a human-readable Boot Order list on single line.
|
||||
*
|
||||
* @return A human readable Boot Order
|
||||
* @return A human-readable Boot Order
|
||||
*/
|
||||
public String toString() {
|
||||
StringBuilder orderList = new StringBuilder();
|
||||
orderList.append("BootOrder = ");
|
||||
orderList.append(" BootOrder = ");
|
||||
for (int i = 0; i < bootOrder.length; i++) {
|
||||
orderList.append(String.format("Boot %04d", (int) bootOrder[i]));
|
||||
orderList.append(String.format("Boot%04d ", (int) bootOrder[i]));
|
||||
}
|
||||
//orderList.append("\n");
|
||||
return orderList.toString();
|
||||
|
@ -23,7 +23,7 @@ import java.util.Arrays;
|
||||
*/
|
||||
public class UefiBootVariable {
|
||||
/**
|
||||
* Human readable description of the variable.
|
||||
* Human-readable description of the variable.
|
||||
*/
|
||||
private String description = "";
|
||||
/**
|
||||
@ -81,7 +81,7 @@ public class UefiBootVariable {
|
||||
* @return string that represents a UEFI boot variable.
|
||||
*/
|
||||
public String toString() {
|
||||
StringBuilder bootInfo = new StringBuilder("Description = ");
|
||||
StringBuilder bootInfo = new StringBuilder(" EFI Load Option = ");
|
||||
// remove all non ascii chars
|
||||
String bootVar = description.replaceAll("[^a-zA-Z_0-0\\s]", "");
|
||||
bootInfo.append(bootVar + "\n" + efiDevPath.toString());
|
||||
|
@ -3,12 +3,23 @@ package hirs.utils.tpm.eventlog.uefi;
|
||||
import hirs.utils.HexUtils;
|
||||
import lombok.Getter;
|
||||
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
/**
|
||||
* Class to process EFI_DEVICE_PATH_PROTOCOL which is referred to as the UEFI_DEVICE_PATH
|
||||
* Class to process a Device Path. A Device Path is a variable-length binary
|
||||
* structure that is made up of variable-length generic Device Path nodes.
|
||||
* The first Device Path node starts at byte offset zero of the Device Path.
|
||||
* The next Device Path node starts at the end of the previous Device Path node.
|
||||
* There is no limit to the number, type, or sequence of nodes in a Device Path.
|
||||
* <p>
|
||||
* Generic Device Path Node Structure:
|
||||
* Name Byte Offset Byte Length Description
|
||||
* Type 0 1 Device path type (such as 0x01 - Hardware Device Path)
|
||||
* Sub-Type 1 1 Sub-Type
|
||||
* Length 2 2 Length of this structure in bytes. Length is 4+n bytes
|
||||
* Data 4 n Specific Device Path data
|
||||
* <p>
|
||||
* EFI_DEVICE_PATH_PROTOCOL:
|
||||
* #define EFI_DEVICE_PATH_PROTOCOL_GUID \09576e91-6d3f-11d2-8e39-00a0c969723b
|
||||
* typedef struct _EFI_DEVICE_PATH_PROTOCOL {
|
||||
* UINT8 Type;
|
||||
@ -23,7 +34,7 @@ import java.nio.charset.StandardCharsets;
|
||||
* Type 0x04 Media Device Path
|
||||
* Type 0x05 BIOS Boot Specification Device Path
|
||||
* Type 0x7F End of Hardware Device Path
|
||||
* Each Type has a sub-type that may or may no be defined in the section
|
||||
* Each Type has a Subtype that may or may not be defined in the section
|
||||
* <p>
|
||||
* Only a few of the SubTypes have been implemented as there are many,
|
||||
* but only those that were reported using the test devices at hand.
|
||||
@ -36,11 +47,11 @@ public class UefiDevicePath {
|
||||
@Getter
|
||||
private String type = "";
|
||||
/**
|
||||
* UEFI Device path sub-type.
|
||||
* UEFI Device path subtype.
|
||||
*/
|
||||
private String subType = "";
|
||||
/**
|
||||
* UEFI Device path human readable description.
|
||||
* UEFI Device path human-readable description.
|
||||
*/
|
||||
private String devPathInfo = "";
|
||||
/**
|
||||
@ -53,9 +64,8 @@ public class UefiDevicePath {
|
||||
* UEFI Device path constructor.
|
||||
*
|
||||
* @param path byte array holding device path data
|
||||
* @throws java.io.UnsupportedEncodingException if path byte array contains unexpected values
|
||||
*/
|
||||
public UefiDevicePath(final byte[] path) throws UnsupportedEncodingException {
|
||||
public UefiDevicePath(final byte[] path) {
|
||||
devPathInfo = processDevPath(path);
|
||||
byte[] lengthBytes = new byte[UefiConstants.SIZE_2];
|
||||
System.arraycopy(path, UefiConstants.OFFSET_2, lengthBytes, 0, UefiConstants.OFFSET_2);
|
||||
@ -63,9 +73,9 @@ public class UefiDevicePath {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the UEFI device sub-type.
|
||||
* Returns the UEFI device subtype.
|
||||
*
|
||||
* @return uefi sub-type
|
||||
* @return uefi subtype
|
||||
*/
|
||||
public String getSubType() {
|
||||
return subType.trim();
|
||||
@ -81,18 +91,17 @@ public class UefiDevicePath {
|
||||
* @return Human readable string containing the device path description.
|
||||
* @throws java.io.UnsupportedEncodingException
|
||||
*/
|
||||
private String processDevPath(final byte[] path) throws UnsupportedEncodingException {
|
||||
private String processDevPath(final byte[] path) {
|
||||
StringBuilder pInfo = new StringBuilder();
|
||||
int devLength = 0, pathOffset = 0, devCount = 0;
|
||||
int devLength = 0;
|
||||
int pathOffset = 0;
|
||||
int devCount = 0;
|
||||
while (true) {
|
||||
Byte devPath = Byte.valueOf(path[pathOffset]);
|
||||
if ((devPath.intValue() == UefiConstants.TERMINATOR)
|
||||
|| (devPath.intValue() == UefiConstants.END_FLAG)) {
|
||||
break;
|
||||
}
|
||||
if (devCount++ > 0) {
|
||||
pInfo.append("\n");
|
||||
}
|
||||
pInfo.append(processDev(path, pathOffset));
|
||||
devLength = path[pathOffset + UefiConstants.OFFSET_3] * UefiConstants.SIZE_256
|
||||
+ path[pathOffset + UefiConstants.OFFSET_2];
|
||||
@ -111,11 +120,10 @@ public class UefiDevicePath {
|
||||
*
|
||||
* @param path
|
||||
* @param offset
|
||||
* @return human readable string representing the UEFI device path
|
||||
* @return human-readable string representing the UEFI device path
|
||||
* @throws java.io.UnsupportedEncodingException
|
||||
*/
|
||||
private String processDev(final byte[] path, final int offset)
|
||||
throws UnsupportedEncodingException {
|
||||
private String processDev(final byte[] path, final int offset) {
|
||||
String devInfo = " ";
|
||||
int devPath = path[offset];
|
||||
byte unknownSubType = path[offset + UefiConstants.OFFSET_1];
|
||||
@ -123,50 +131,50 @@ public class UefiDevicePath {
|
||||
case UefiConstants.DEV_HW:
|
||||
type = "Hardware Device Path";
|
||||
if (devPath == UefiConstants.DEVPATH_HARWARE) {
|
||||
devInfo += type + ": " + pciSubType(path, offset);
|
||||
devInfo += type + ":\n" + pciSubType(path, offset);
|
||||
}
|
||||
break;
|
||||
case UefiConstants.DEV_ACPI:
|
||||
type = "ACPI Device Path";
|
||||
devInfo += type + ": " + acpiSubType(path, offset);
|
||||
devInfo += type + ":\n" + acpiSubType(path, offset);
|
||||
break;
|
||||
case UefiConstants.DEV_MSG:
|
||||
type = "Messaging Device Path";
|
||||
if (path[offset + UefiConstants.OFFSET_1] == UefiConstants.DEV_SUB_SATA) {
|
||||
devInfo += type + ": " + sataSubType(path, offset);
|
||||
devInfo += type + ":\n" + sataSubType(path, offset);
|
||||
} else if (path[offset + UefiConstants.OFFSET_1] == UefiConstants.DEV_SUB_NVM) {
|
||||
devInfo += type + ": " + nvmSubType(path, offset);
|
||||
devInfo += type + ":\n" + nvmSubType(path, offset);
|
||||
} else if (path[offset + UefiConstants.OFFSET_1] == UefiConstants.DEV_SUB_USB) {
|
||||
devInfo += type + ": " + usbSubType(path, offset);
|
||||
devInfo += type + ":\n" + usbSubType(path, offset);
|
||||
} else {
|
||||
devInfo += "UEFI Messaging Device Path Type " + Integer.valueOf(unknownSubType);
|
||||
devInfo += "UEFI Messaging Device Path Type " + Integer.valueOf(unknownSubType) + "\n";
|
||||
}
|
||||
break;
|
||||
case UefiConstants.DEV_MEDIA:
|
||||
type = "Media Device Path";
|
||||
if (path[offset + UefiConstants.OFFSET_1] == 0x01) {
|
||||
devInfo += type + ": " + hardDriveSubType(path, offset);
|
||||
devInfo += type + ":\n" + hardDriveSubType(path, offset);
|
||||
} else if (path[offset + UefiConstants.OFFSET_1] == UefiConstants.DEVPATH_VENDOR) {
|
||||
devInfo += type + ": " + vendorSubType(path, offset);
|
||||
devInfo += type + ":\n" + vendorSubType(path, offset);
|
||||
} else if (path[offset + UefiConstants.OFFSET_1] == UefiConstants.DEVPATH_FILE) {
|
||||
devInfo += type + ": " + filePathSubType(path, offset);
|
||||
devInfo += type + ":\n" + filePathSubType(path, offset);
|
||||
} else if (path[offset + UefiConstants.OFFSET_1] == UefiConstants.DEVPATH_PWIG_FILE) {
|
||||
devInfo += type + ": " + piwgFirmVolFile(path, offset);
|
||||
devInfo += type + ":\n" + piwgFirmVolFile(path, offset);
|
||||
} else if (path[offset + UefiConstants.OFFSET_1] == UefiConstants.DEVPATH_PWIG_VOL) {
|
||||
devInfo += type + ": " + piwgFirmVolPath(path, offset);
|
||||
devInfo += type + ":\n" + piwgFirmVolPath(path, offset);
|
||||
} else {
|
||||
devInfo += "UEFI Media Device Path Type " + Integer.valueOf(unknownSubType);
|
||||
devInfo += "UEFI Media Device Path Type " + Integer.valueOf(unknownSubType) + "\n";
|
||||
}
|
||||
break;
|
||||
case UefiConstants.DEV_BIOS:
|
||||
type = "BIOS Device Path";
|
||||
devInfo += type + ": " + biosDevicePath(path, offset);
|
||||
devInfo += type + ":\n" + biosDevicePath(path, offset);
|
||||
break;
|
||||
case UefiConstants.TERMINATOR:
|
||||
devInfo += "End of Hardware Device Path";
|
||||
devInfo += "End of Hardware Device Path\n";
|
||||
break;
|
||||
default:
|
||||
devInfo += "UEFI Device Path Type " + Integer.valueOf(unknownSubType);
|
||||
devInfo += "UEFI Device Path Type " + Integer.valueOf(unknownSubType) + "\n";
|
||||
}
|
||||
return devInfo;
|
||||
}
|
||||
@ -179,17 +187,17 @@ public class UefiDevicePath {
|
||||
* @return acpi device info
|
||||
*/
|
||||
private String acpiSubType(final byte[] path, final int offset) {
|
||||
subType = "";
|
||||
subType = " Sub Type = ACPI\n";
|
||||
switch (path[offset + UefiConstants.OFFSET_1]) {
|
||||
case 0x01:
|
||||
subType = "(Short): ";
|
||||
case 0x01: // standard version
|
||||
subType += acpiShortSubType(path, offset);
|
||||
break;
|
||||
case 0x02:
|
||||
subType = "Expanded ACPI Device Path";
|
||||
subType = "(expanded version):\n";
|
||||
// tbd
|
||||
break;
|
||||
default:
|
||||
subType = "Invalid ACPI Device Path sub type";
|
||||
subType = "Invalid ACPI Device Path sub type\n";
|
||||
}
|
||||
return subType;
|
||||
}
|
||||
@ -205,9 +213,13 @@ public class UefiDevicePath {
|
||||
subType = "";
|
||||
byte[] hid = new byte[UefiConstants.SIZE_4];
|
||||
System.arraycopy(path, UefiConstants.OFFSET_4 + offset, hid, 0, UefiConstants.SIZE_4);
|
||||
subType += "_HID = " + HexUtils.byteArrayToHexString(hid);
|
||||
subType += " _HID = " + HexUtils.byteArrayToHexString(hid) + "\n";
|
||||
System.arraycopy(path, 2 * UefiConstants.SIZE_4 + offset, hid, 0, UefiConstants.SIZE_4);
|
||||
subType += "_UID = " + HexUtils.byteArrayToHexString(hid);
|
||||
String uid = HexUtils.byteArrayToHexString(hid);
|
||||
if (uid.contains("00000000")) {
|
||||
uid = "No _UID exists for this device";
|
||||
}
|
||||
subType += " _UID = " + uid + "\n";
|
||||
return subType;
|
||||
}
|
||||
|
||||
@ -219,22 +231,25 @@ public class UefiDevicePath {
|
||||
* @return pci device info.
|
||||
*/
|
||||
private String pciSubType(final byte[] path, final int offset) {
|
||||
subType = "PCI: PCI Function Number = ";
|
||||
subType = " Sub Type = PCI\n";
|
||||
subType += " PCI Function Number = ";
|
||||
subType += String.format("0x%x", path[offset + UefiConstants.SIZE_4]);
|
||||
subType += " PCI Device Number = ";
|
||||
subType += "\n PCI Device Number = ";
|
||||
subType += String.format("0x%x", path[offset + UefiConstants.SIZE_5]);
|
||||
subType += "\n";
|
||||
return subType;
|
||||
}
|
||||
|
||||
/**
|
||||
* processes the SATA sub type.
|
||||
* processes the SATA subtype.
|
||||
*
|
||||
* @param path
|
||||
* @param offset
|
||||
* @return SATA drive info.
|
||||
*/
|
||||
private String sataSubType(final byte[] path, final int offset) {
|
||||
subType = "SATA: HBA Port Number = ";
|
||||
subType = " Sub Type = SATA\n";
|
||||
subType += " SATA: HBA Port Number = ";
|
||||
byte[] data = new byte[UefiConstants.SIZE_2];
|
||||
System.arraycopy(path, UefiConstants.OFFSET_4 + offset, data, 0, UefiConstants.SIZE_2);
|
||||
subType += HexUtils.byteArrayToHexString(data);
|
||||
@ -242,18 +257,20 @@ public class UefiDevicePath {
|
||||
subType += " Port Multiplier = " + HexUtils.byteArrayToHexString(data);
|
||||
System.arraycopy(path, UefiConstants.OFFSET_8 + offset, data, 0, UefiConstants.SIZE_2);
|
||||
subType += " Logical Unit Number = " + HexUtils.byteArrayToHexString(data);
|
||||
subType += "\n";
|
||||
return subType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Processes the hard drive sub type.
|
||||
* Processes the hard drive subtype.
|
||||
*
|
||||
* @param path
|
||||
* @param offset
|
||||
* @return hard drive info.
|
||||
*/
|
||||
private String hardDriveSubType(final byte[] path, final int offset) {
|
||||
subType = "Partition Number = ";
|
||||
subType = " Sub Type = Hard Drive\n";
|
||||
subType += " Partition Number = ";
|
||||
byte[] partnumber = new byte[UefiConstants.SIZE_4];
|
||||
System.arraycopy(path, UefiConstants.OFFSET_4 + offset, partnumber,
|
||||
0, UefiConstants.SIZE_4);
|
||||
@ -261,14 +278,14 @@ public class UefiDevicePath {
|
||||
byte[] data = new byte[UefiConstants.SIZE_8];
|
||||
System.arraycopy(path, UefiConstants.OFFSET_8 + offset, data, 0,
|
||||
UefiConstants.SIZE_8);
|
||||
subType += " Partition Start = " + HexUtils.byteArrayToHexString(data);
|
||||
subType += "\n Partition Start = " + HexUtils.byteArrayToHexString(data);
|
||||
System.arraycopy(path, UefiConstants.OFFSET_16 + offset, data, 0,
|
||||
UefiConstants.SIZE_8);
|
||||
subType += " Partition Size = " + HexUtils.byteArrayToHexString(data);
|
||||
subType += "\n Partition Size = " + HexUtils.byteArrayToHexString(data);
|
||||
byte[] signature = new byte[UefiConstants.SIZE_16];
|
||||
System.arraycopy(path, UefiConstants.OFFSET_24 + offset, signature, 0,
|
||||
UefiConstants.SIZE_16);
|
||||
subType += "\n Partition Signature = ";
|
||||
subType += "\n Partition Signature = ";
|
||||
if (path[UefiConstants.OFFSET_41 + offset] == UefiConstants.DRIVE_SIG_NONE) {
|
||||
subType += "None";
|
||||
} else if (path[UefiConstants.OFFSET_41 + offset] == UefiConstants.DRIVE_SIG_32BIT) {
|
||||
@ -279,26 +296,28 @@ public class UefiDevicePath {
|
||||
} else {
|
||||
subType += "invalid partition signature type";
|
||||
}
|
||||
subType += " Partition Format = ";
|
||||
subType += "\n Partition Format = ";
|
||||
if (path[UefiConstants.OFFSET_40 + offset] == UefiConstants.DRIVE_TYPE_PC_AT) {
|
||||
subType += " PC-AT compatible legacy MBR";
|
||||
subType += "PC-AT compatible legacy MBR";
|
||||
} else if (path[UefiConstants.OFFSET_40 + offset] == UefiConstants.DRIVE_TYPE_GPT) {
|
||||
subType += " GUID Partition Table";
|
||||
subType += "GUID Partition Table";
|
||||
} else {
|
||||
subType += " Invalid partition table type";
|
||||
subType += "Invalid partition table type";
|
||||
}
|
||||
subType += "\n";
|
||||
return subType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Process the File path sub type.
|
||||
* Process the File path subtype.
|
||||
*
|
||||
* @param path
|
||||
* @param offset
|
||||
* @return file path info.
|
||||
*/
|
||||
private String filePathSubType(final byte[] path, final int offset) {
|
||||
subType = "File Path = ";
|
||||
subType = " Sub Type = File Path\n";
|
||||
subType += " File Path = ";
|
||||
byte[] lengthBytes = new byte[UefiConstants.SIZE_2];
|
||||
System.arraycopy(path, 2 + offset, lengthBytes, 0, UefiConstants.SIZE_2);
|
||||
int subTypeLength = HexUtils.leReverseInt(lengthBytes);
|
||||
@ -307,11 +326,12 @@ public class UefiDevicePath {
|
||||
0, subTypeLength);
|
||||
byte[] fileName = convertChar16tobyteArray(filePath);
|
||||
subType += new String(fileName, StandardCharsets.UTF_8);
|
||||
subType += "\n";
|
||||
return subType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Process a vendor sub-type on a Media Type.
|
||||
* Process a vendor subtype on a Media Type.
|
||||
* Length of this structure in bytes. Length is 20 + n bytes
|
||||
* Vendor-assigned GUID that defines the data that follows.
|
||||
* Vendor-defined variable size data.
|
||||
@ -321,7 +341,8 @@ public class UefiDevicePath {
|
||||
* @return vendor device info.
|
||||
*/
|
||||
private String vendorSubType(final byte[] path, final int offset) {
|
||||
subType = "Vendor Subtype GUID = ";
|
||||
subType = " Sub Type = Vendor\n";
|
||||
subType += " Vendor Subtype GUID = ";
|
||||
byte[] lengthBytes = new byte[UefiConstants.SIZE_2];
|
||||
System.arraycopy(path, UefiConstants.OFFSET_2 + offset, lengthBytes,
|
||||
0, UefiConstants.SIZE_2);
|
||||
@ -337,8 +358,9 @@ public class UefiDevicePath {
|
||||
+ offset, vendorData, 0, subTypeLength - UefiConstants.SIZE_16);
|
||||
subType += " : Vendor Data = " + HexUtils.byteArrayToHexString(vendorData);
|
||||
} else {
|
||||
subType += " : No Vendor Data pesent";
|
||||
subType += " : No Vendor Data present";
|
||||
}
|
||||
subType += "\n";
|
||||
return subType;
|
||||
}
|
||||
|
||||
@ -351,8 +373,8 @@ public class UefiDevicePath {
|
||||
* @return USB device info.
|
||||
*/
|
||||
private String usbSubType(final byte[] path, final int offset) {
|
||||
subType = " USB ";
|
||||
subType += " port = " + Integer.valueOf(path[offset + UefiConstants.OFFSET_4]);
|
||||
subType = " Sub Type = USB\n";
|
||||
subType += " port = " + Integer.valueOf(path[offset + UefiConstants.OFFSET_4]);
|
||||
subType += " interface = " + Integer.valueOf(path[offset + UefiConstants.OFFSET_5]);
|
||||
byte[] lengthBytes = new byte[UefiConstants.SIZE_2];
|
||||
System.arraycopy(path, UefiConstants.OFFSET_2 + offset, lengthBytes,
|
||||
@ -361,6 +383,7 @@ public class UefiDevicePath {
|
||||
byte[] usbData = new byte[subTypeLength];
|
||||
System.arraycopy(path, UefiConstants.OFFSET_4 + offset, usbData,
|
||||
0, subTypeLength);
|
||||
subType += "\n";
|
||||
// Todo add further USB processing ...
|
||||
return subType;
|
||||
}
|
||||
@ -377,7 +400,8 @@ public class UefiDevicePath {
|
||||
* @return NVM device info.
|
||||
*/
|
||||
private String nvmSubType(final byte[] path, final int offset) {
|
||||
subType = "NVM Express Namespace = ";
|
||||
subType = " Sub Type = NVM\n";
|
||||
subType += " NVM Express Namespace = ";
|
||||
byte[] lengthBytes = new byte[UefiConstants.SIZE_2];
|
||||
System.arraycopy(path, UefiConstants.OFFSET_2 + offset, lengthBytes,
|
||||
0, UefiConstants.SIZE_2);
|
||||
@ -386,6 +410,7 @@ public class UefiDevicePath {
|
||||
System.arraycopy(path, UefiConstants.OFFSET_4 + offset, nvmData,
|
||||
0, subTypeLength);
|
||||
subType += HexUtils.byteArrayToHexString(nvmData);
|
||||
subType += "\n";
|
||||
return subType;
|
||||
}
|
||||
|
||||
@ -400,7 +425,8 @@ public class UefiDevicePath {
|
||||
* @return String that represents the UEFI defined BIOS Device Type.
|
||||
*/
|
||||
private String biosDevicePath(final byte[] path, final int offset) {
|
||||
subType = "Legacy BIOS : Type = ";
|
||||
subType = " Sub Type = Bios Device Path\n";
|
||||
subType += " Legacy BIOS : Type = ";
|
||||
Byte pathType = Byte.valueOf(path[offset + 1]);
|
||||
switch (pathType.intValue()) {
|
||||
case UefiConstants.DEVPATH_BIOS_RESERVED:
|
||||
@ -432,6 +458,7 @@ public class UefiDevicePath {
|
||||
subType += "Unknown";
|
||||
break;
|
||||
}
|
||||
subType += "\n";
|
||||
return subType;
|
||||
}
|
||||
|
||||
@ -446,12 +473,13 @@ public class UefiDevicePath {
|
||||
* @return String that represents the PIWG Firmware Volume Path
|
||||
*/
|
||||
private String piwgFirmVolFile(final byte[] path, final int offset) {
|
||||
subType = "PIWG Firmware File ";
|
||||
subType = " Sub Type = PIWG Firmware Volume File\n";
|
||||
byte[] guidData = new byte[UefiConstants.SIZE_16];
|
||||
System.arraycopy(path, UefiConstants.OFFSET_4 + offset, guidData,
|
||||
0, UefiConstants.SIZE_16);
|
||||
UefiGuid guid = new UefiGuid(guidData);
|
||||
subType += guid.toString();
|
||||
subType += "\n";
|
||||
return subType;
|
||||
}
|
||||
|
||||
@ -466,12 +494,13 @@ public class UefiDevicePath {
|
||||
* @return String that represents the PIWG Firmware Volume Path
|
||||
*/
|
||||
private String piwgFirmVolPath(final byte[] path, final int offset) {
|
||||
subType = "PIWG Firmware Volume ";
|
||||
subType = " Sub Type = PIWG Firmware Volume Path\n";
|
||||
byte[] guidData = new byte[UefiConstants.SIZE_16];
|
||||
System.arraycopy(path, UefiConstants.OFFSET_4 + offset, guidData,
|
||||
0, UefiConstants.SIZE_16);
|
||||
UefiGuid guid = new UefiGuid(guidData);
|
||||
subType += guid.toString();
|
||||
subType += "\n";
|
||||
return subType;
|
||||
}
|
||||
|
||||
|
@ -28,20 +28,20 @@ public class UefiGuid {
|
||||
*/
|
||||
private static final int UUID_EPOCH_DIVISOR = 10000;
|
||||
/**
|
||||
* Filesystem path of vendor-table.json
|
||||
* Filesystem path of vendor-table.json.
|
||||
*/
|
||||
private static final Path JSON_PATH = FileSystems.getDefault().getPath("/etc",
|
||||
"hirs", "aca", "default-properties", "vendor-table.json");
|
||||
/**
|
||||
* Name of vendor-table file in code
|
||||
* Name of vendor-table file in code.
|
||||
*/
|
||||
private static final String JSON_FILENAME = "vendor-table.json";
|
||||
/**
|
||||
* Reference to the vendor-table json object
|
||||
* Reference to the vendor-table json object.
|
||||
*/
|
||||
private JsonObject uefiVendorRef;
|
||||
/**
|
||||
* Track status of vendor-table.json
|
||||
* Track status of vendor-table.json.
|
||||
*/
|
||||
@Getter
|
||||
private String vendorTableFileStatus = FILESTATUS_NOT_ACCESSIBLE;
|
||||
@ -77,13 +77,12 @@ public class UefiGuid {
|
||||
uefiVendorRef = JsonUtils.getSpecificJsonObject(vendorPathString,
|
||||
"VendorTable");
|
||||
|
||||
if(!isVendorTableReferenceHandleEmpty()) {
|
||||
if (!isVendorTableReferenceHandleEmpty()) {
|
||||
vendorTableFileStatus = FILESTATUS_FROM_FILESYSTEM;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
// could not access vendor-table.json from filesystem, so attempt to access from code
|
||||
uefiVendorRef = JsonUtils.getSpecificJsonObject(JSON_FILENAME, "VendorTable");
|
||||
if(!isVendorTableReferenceHandleEmpty()) {
|
||||
if (!isVendorTableReferenceHandleEmpty()) {
|
||||
vendorTableFileStatus = FILESTATUS_FROM_CODE;
|
||||
}
|
||||
}
|
||||
|
@ -38,18 +38,18 @@ public class UefiSecureBoot {
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides a human readable value for the Secure Boot variable.
|
||||
* Provides a human-readable value for the Secure Boot variable.
|
||||
*
|
||||
* @return Human readable description.
|
||||
*/
|
||||
public String toString() {
|
||||
if (!berror) {
|
||||
if (secureBootVariable == 1) {
|
||||
info += " Secure Boot is enabled ";
|
||||
info += " Secure Boot is enabled ";
|
||||
} else if (secureBootVariable == 0) {
|
||||
info += " Secure Boot is NOT enabled ";
|
||||
info += " Secure Boot is NOT enabled ";
|
||||
} else {
|
||||
info += " Unkown State: Secure Variable is undefined ";
|
||||
info += " Unknown State: Secure Variable is undefined ";
|
||||
}
|
||||
}
|
||||
return info;
|
||||
|
@ -10,9 +10,15 @@ import java.security.NoSuchAlgorithmException;
|
||||
import java.security.cert.CertificateException;
|
||||
|
||||
/**
|
||||
* Class for processing the contents of a Secure Boot PK, KEK, DB or DBX contents.
|
||||
* used for EFIVariables associated with Secure Boot
|
||||
* as defined by Section 32.4.1 Signature Database from the UEFI 2.8 specification
|
||||
* Class for processing either
|
||||
* 1) the contents of a Secure Boot PK, KEK, DB or DBX contents,
|
||||
* used for EFIVariables associated with Secure Boot,
|
||||
* as defined by Section 32.4.1 Signature Database from the UEFI 2.8 specification
|
||||
* 2) the contents of an SPDM devdb,
|
||||
* used for SPDM Device Policy or Device Authority, whose data is an EFIVariable
|
||||
* EFIVariable data for SPDM Device Policy: UefiSignatureList
|
||||
* EFIVariable data for SPDM Device: UefiSignatureData only
|
||||
* as defined by PFP v1.06 Rev52, Section 10.4
|
||||
* <p>
|
||||
* typedef struct _EFI_SIGNATURE_DATA {
|
||||
* EFI_GUID SignatureOwner;
|
||||
@ -67,8 +73,8 @@ public class UefiSignatureData {
|
||||
*
|
||||
* @param inputStream The Signature data.
|
||||
* @param sigType UEFI defined signature type.
|
||||
* @throws java.io.IOException if there's an problem reading the input stream.
|
||||
* @throws java.security.cert.CertificateException If there a problem parsing the X509 certificate.
|
||||
* @throws java.io.IOException if there's a problem reading the input stream.
|
||||
* @throws java.security.cert.CertificateException If there's a problem parsing the X509 certificate.
|
||||
* @throws java.security.NoSuchAlgorithmException if there's a problem hashing the certificate.
|
||||
*/
|
||||
UefiSignatureData(final ByteArrayInputStream inputStream, final UefiGuid sigType)
|
||||
|
@ -12,12 +12,18 @@ import java.util.ArrayList;
|
||||
import static hirs.utils.tpm.eventlog.uefi.UefiConstants.FILESTATUS_NOT_ACCESSIBLE;
|
||||
|
||||
/**
|
||||
* Class for processing the contents of a Secure Boot DB or DBX contents.
|
||||
* used for EFIVariables associated with Secure Boot
|
||||
* as defined by Section 32.4.1 Signature Database from the UEFI 2.8 specification.
|
||||
* Class for processing either
|
||||
* 1) the contents of a Secure Boot PK, KEK, DB or DBX contents,
|
||||
* used for EFIVariables associated with Secure Boot,
|
||||
* as defined by Section 32.4.1 Signature Database from the UEFI 2.8 specification
|
||||
* 2) the contents of an SPDM devdb,
|
||||
* used for SPDM Device Policy, whose data is an EFIVariable
|
||||
* as defined by PFP v1.06 Rev52, Section 10.4
|
||||
* <p>
|
||||
* An EFI Signature List is actual a list of Certificates used to verify a Signature.
|
||||
* This is mainly found in PCR[7] UEFI variables for the Secure Boot PK, KEK, Db and DBx variables.
|
||||
* An EFI Signature List is actually a list of Certificates used to verify a Signature.
|
||||
* This is mainly found in PCR[7] UEFI variables for either the
|
||||
* Secure Boot PK, KEK, Db and DBx variables
|
||||
* or the SPDM devdb variable (under EV_EFI_SPDM_DEVICE_POLICY).
|
||||
* <p>
|
||||
* typedef struct _EFI_SIGNATURE_LIST {
|
||||
* EFI_GUID SignatureType;
|
||||
@ -27,6 +33,35 @@ import static hirs.utils.tpm.eventlog.uefi.UefiConstants.FILESTATUS_NOT_ACCESSIB
|
||||
* // UINT8 SignatureHeader[SignatureHeaderSize];
|
||||
* // EFI_SIGNATURE_DATA Signatures[...][SignatureSize];
|
||||
* } EFI_SIGNATURE_LIST;
|
||||
*
|
||||
* SignatureListHeader (contents common to any Signature Type)
|
||||
* - SignatureType
|
||||
* - SignatureListSize
|
||||
* - SignatureHeaderSize
|
||||
* - SignatureSize
|
||||
* SignatureHeader (contents depend on the SignatureType)
|
||||
* - The format of this header is specified by the SignatureType (SHA256, X509).
|
||||
* Signatures[][] is an array of signatures.
|
||||
* - Each signature is SignatureSize bytes in length.
|
||||
* - The format of the signature is defined by SignatureType (SHA256, X509).
|
||||
*
|
||||
* / |-------------------------| ------- SignatureType
|
||||
* / | Signature List Header | SignatureListSize
|
||||
* |---------------------| / |-------------------------|\ SignatureHeaderSize
|
||||
* | Signature List #0 | / | Signature Header | \ _____ SignatureSize
|
||||
* | | / |-------------------------|
|
||||
* |---------------------| / | Signature #0 |
|
||||
* | Signature List #1 | / |-------------------------|
|
||||
* |---------------------|/ | Signature #1 | --> each Signature is
|
||||
* | Signature List #2 | |-------------------------| 1 UefiSignatureData
|
||||
* | | | Signature #2 | (1 cert or hash)
|
||||
* | | |-------------------------|
|
||||
* |---------------------| | ... |
|
||||
* \ | |
|
||||
* \ |-------------------------|
|
||||
* \ | Signature #n |
|
||||
* \ |-------------------------|
|
||||
*
|
||||
*/
|
||||
public class UefiSignatureList {
|
||||
/**
|
||||
@ -58,7 +93,7 @@ public class UefiSignatureList {
|
||||
/**
|
||||
* Current status of Signature List data.
|
||||
*/
|
||||
private String dataStatus = "Signature List data validity is undetermined yet";
|
||||
private String dataInvalidStatus = "Signature List data validity is undetermined yet";
|
||||
/**
|
||||
* Array List of Signature found in the list.
|
||||
*/
|
||||
@ -72,42 +107,42 @@ public class UefiSignatureList {
|
||||
*/
|
||||
private UefiGuid signatureType = null;
|
||||
/**
|
||||
* Track status of vendor-table.json
|
||||
* Track status of vendor-table.json.
|
||||
*/
|
||||
@Getter
|
||||
private String vendorTableFileStatus = FILESTATUS_NOT_ACCESSIBLE;
|
||||
|
||||
/**
|
||||
* UefiSignatureList constructor.
|
||||
*
|
||||
* @param list byte array holding the signature list.
|
||||
* @throws java.security.cert.CertificateException If there a problem parsing the X509 certificate.
|
||||
* @throws java.security.NoSuchAlgorithmException if there's a problem hashing the certificate.
|
||||
* @throws java.io.IOException If there's a problem parsing the signature data.
|
||||
*/
|
||||
UefiSignatureList(final byte[] list)
|
||||
throws CertificateException, NoSuchAlgorithmException, IOException {
|
||||
|
||||
byte[] guid = new byte[UefiConstants.SIZE_16];
|
||||
System.arraycopy(list, 0, guid, 0, UefiConstants.SIZE_16);
|
||||
signatureType = new UefiGuid(guid);
|
||||
vendorTableFileStatus = signatureType.getVendorTableFileStatus();
|
||||
|
||||
byte[] lSize = new byte[UefiConstants.SIZE_4];
|
||||
System.arraycopy(list, UefiConstants.OFFSET_16, lSize, 0, UefiConstants.SIZE_4);
|
||||
listSize = HexUtils.leReverseInt(lSize);
|
||||
|
||||
byte[] hSize = new byte[UefiConstants.SIZE_4];
|
||||
System.arraycopy(list, UefiConstants.OFFSET_20, hSize, 0, UefiConstants.SIZE_4);
|
||||
|
||||
byte[] sSize = new byte[UefiConstants.SIZE_4];
|
||||
System.arraycopy(list, UefiConstants.OFFSET_24, sSize, 0, UefiConstants.SIZE_4);
|
||||
signatureSize = HexUtils.leReverseInt(sSize);
|
||||
|
||||
sigData = new byte[signatureSize];
|
||||
System.arraycopy(list, UefiConstants.OFFSET_28, sigData, 0, signatureSize);
|
||||
processSignatureList(sigData);
|
||||
}
|
||||
// /**
|
||||
// * UefiSignatureList constructor.
|
||||
// *
|
||||
// * @param list byte array holding the signature list.
|
||||
// * @throws java.security.cert.CertificateException If there a problem parsing the X509 certificate.
|
||||
// * @throws java.security.NoSuchAlgorithmException if there's a problem hashing the certificate.
|
||||
// * @throws java.io.IOException If there's a problem parsing the signature data.
|
||||
// */
|
||||
// UefiSignatureList(final byte[] list)
|
||||
// throws CertificateException, NoSuchAlgorithmException, IOException {
|
||||
//
|
||||
// byte[] guid = new byte[UefiConstants.SIZE_16];
|
||||
// System.arraycopy(list, 0, guid, 0, UefiConstants.SIZE_16);
|
||||
// signatureType = new UefiGuid(guid);
|
||||
// vendorTableFileStatus = signatureType.getVendorTableFileStatus();
|
||||
//
|
||||
// byte[] lSize = new byte[UefiConstants.SIZE_4];
|
||||
// System.arraycopy(list, UefiConstants.OFFSET_16, lSize, 0, UefiConstants.SIZE_4);
|
||||
// listSize = HexUtils.leReverseInt(lSize);
|
||||
//
|
||||
// byte[] hSize = new byte[UefiConstants.SIZE_4];
|
||||
// System.arraycopy(list, UefiConstants.OFFSET_20, hSize, 0, UefiConstants.SIZE_4);
|
||||
//
|
||||
// byte[] sSize = new byte[UefiConstants.SIZE_4];
|
||||
// System.arraycopy(list, UefiConstants.OFFSET_24, sSize, 0, UefiConstants.SIZE_4);
|
||||
// signatureSize = HexUtils.leReverseInt(sSize);
|
||||
//
|
||||
// sigData = new byte[signatureSize];
|
||||
// System.arraycopy(list, UefiConstants.OFFSET_28, sigData, 0, signatureSize);
|
||||
// processSignatureList(sigData);
|
||||
// }
|
||||
|
||||
/**
|
||||
* EFI Signature list constructor.
|
||||
@ -125,10 +160,9 @@ public class UefiSignatureList {
|
||||
vendorTableFileStatus = signatureType.getVendorTableFileStatus();
|
||||
|
||||
// if signatureType is invalid, don't even process any of the data
|
||||
// however, if signatureTYpe is valid, but some of the data later on is invalid, that will
|
||||
// however, if signatureType is valid, but some of the data later on is invalid, that will
|
||||
// be caught when UefiSignatureData is processed
|
||||
if (!isValidSigListGUID(signatureType)) {
|
||||
//processSignatureData(lists);
|
||||
signatureTypeValid = false;
|
||||
} else { // valid SigData Processing
|
||||
signatureTypeValid = true;
|
||||
@ -164,7 +198,7 @@ public class UefiSignatureList {
|
||||
UefiSignatureData tmpSigData = new UefiSignatureData(efiSigDataIS, signatureType);
|
||||
if (!tmpSigData.isValid()) {
|
||||
dataValid = false;
|
||||
dataStatus = tmpSigData.getStatus();
|
||||
dataInvalidStatus = tmpSigData.getStatus();
|
||||
break;
|
||||
}
|
||||
sigList.add(tmpSigData);
|
||||
@ -172,28 +206,6 @@ public class UefiSignatureList {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Method for processing a set of EFI SignatureList(s).
|
||||
*
|
||||
* @param sigDataIS Byte array holding one or more SignatureLists.
|
||||
* @throws java.security.cert.CertificateException If there's a problem parsing the X509 certificate.
|
||||
* @throws java.security.NoSuchAlgorithmException if there's a problem hashing the certificate.
|
||||
* @throws java.io.IOException If there's a problem parsing the signature data.
|
||||
*/
|
||||
private void processSignatureData(final ByteArrayInputStream sigDataIS)
|
||||
throws CertificateException, NoSuchAlgorithmException, IOException {
|
||||
while (sigDataIS.available() > 0) {
|
||||
UefiSignatureData tmpigData = new UefiSignatureData(sigDataIS, signatureType);
|
||||
if (!tmpigData.isValid()) {
|
||||
dataValid = false;
|
||||
dataStatus = tmpigData.getStatus();
|
||||
break;
|
||||
}
|
||||
sigList.add(tmpigData);
|
||||
numberOfCerts++;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks to see if GUID is listed on page 1729 of UEFI spec version 2.8.
|
||||
*
|
||||
@ -223,19 +235,21 @@ public class UefiSignatureList {
|
||||
StringBuilder sigInfo = new StringBuilder();
|
||||
|
||||
if (!signatureTypeValid) {
|
||||
sigInfo.append(" *** Unknown UEFI Signature Type encountered:\n" +
|
||||
" " + signatureType.toString() + "\n");
|
||||
}
|
||||
else {
|
||||
sigInfo.append(" *** Unknown UEFI Signature Type encountered:\n"
|
||||
+ " " + signatureType.toString() + "\n");
|
||||
} else {
|
||||
sigInfo.append(" UEFI Signature List Type = " + signatureType.toString() + "\n");
|
||||
sigInfo.append(" Number of Certs or Hashes in UEFI Signature List = " + numberOfCerts + "\n");
|
||||
|
||||
int certOrHashCnt = 1;
|
||||
for (int i = 0; i < sigList.size(); i++) {
|
||||
sigInfo.append(" Cert or Hash # " + certOrHashCnt++ + " of "
|
||||
+ numberOfCerts + ": ------------------\n");
|
||||
UefiSignatureData certData = sigList.get(i);
|
||||
sigInfo.append(certData.toString());
|
||||
}
|
||||
if (!dataValid) {
|
||||
sigInfo.append(" *** Invalid UEFI Signature data encountered: " + dataStatus + "\n");
|
||||
sigInfo.append(" *** Invalid UEFI Signature data encountered: " + dataInvalidStatus + "\n");
|
||||
}
|
||||
}
|
||||
return sigInfo.toString();
|
||||
|
@ -42,11 +42,11 @@ public class UefiVariable {
|
||||
@Getter
|
||||
private String efiVarName = "";
|
||||
/**
|
||||
* Encountered invalid UEFI Signature List
|
||||
* Encountered invalid UEFI Signature List.
|
||||
*/
|
||||
private boolean invalidSignatureListEncountered = false;
|
||||
/**
|
||||
* Invalid UEFI Signature List
|
||||
* Invalid UEFI Signature List.
|
||||
*/
|
||||
private String invalidSignatureListStatus = "";
|
||||
/**
|
||||
@ -75,6 +75,11 @@ public class UefiVariable {
|
||||
@Getter
|
||||
private String vendorTableFileStatus = FILESTATUS_FROM_FILESYSTEM;
|
||||
|
||||
/**
|
||||
* Human-readable description of the data within the SPDM devdc (to be updated with more test data).
|
||||
*/
|
||||
private String spdmDevdcInfo = "";
|
||||
|
||||
/**
|
||||
* EFIVariable constructor.
|
||||
* The UEFI_VARIABLE_DATA contains a "VariableName" field which is used to determine
|
||||
@ -128,10 +133,16 @@ public class UefiVariable {
|
||||
case "dbx":
|
||||
processSigList(uefiVariableData);
|
||||
break;
|
||||
case "devdb": // Update when test patterns exist
|
||||
break; // PFP v1.06 Rev 52, Sec 3.3.4.8
|
||||
case "devdb":
|
||||
processSigList(uefiVariableData);
|
||||
break; // Update when test patterns exist
|
||||
// PFP v1.06 Rev 52, Sec 3.3.4.8
|
||||
// EV_EFI_SPDM_DEVICE_POLICY: EFI_SIGNATURE_LIST
|
||||
// EV_EFI_SPDM_DEVICE_AUTHORITY: EFI_SIGNATURE_DATA
|
||||
// for now, differentiate them by using devdc for ..DEVICE_AUTHORITY
|
||||
case "devdc":
|
||||
processSigDataX509(uefiVariableData);
|
||||
break;
|
||||
case "Boot00":
|
||||
bootv = new UefiBootVariable(uefiVariableData);
|
||||
break;
|
||||
@ -173,13 +184,13 @@ public class UefiVariable {
|
||||
// the if statement is executed
|
||||
// [new event file status = list.getVendorTableFileStatus()]
|
||||
// (ie. if the new file status is not-accessible or from-code, then want to update)
|
||||
if((vendorTableFileStatus != FILESTATUS_NOT_ACCESSIBLE) &&
|
||||
(list.getVendorTableFileStatus() != FILESTATUS_FROM_FILESYSTEM)) {
|
||||
if ((vendorTableFileStatus != FILESTATUS_NOT_ACCESSIBLE)
|
||||
&& (list.getVendorTableFileStatus() != FILESTATUS_FROM_FILESYSTEM)) {
|
||||
vendorTableFileStatus = list.getVendorTableFileStatus();
|
||||
}
|
||||
|
||||
// efiVariableSigListContents += list.toString();
|
||||
if(!list.isSignatureTypeValid()) {
|
||||
if (!list.isSignatureTypeValid()) {
|
||||
invalidSignatureListEncountered = true;
|
||||
invalidSignatureListStatus = list.toString();
|
||||
break;
|
||||
@ -188,18 +199,64 @@ public class UefiVariable {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Method for processing the data in an EFI Signature Data, where the data is known to be an X509 cert.
|
||||
*
|
||||
* @param efiSigData Byte array holding the SignatureData data
|
||||
* @throws java.security.cert.CertificateException If there's a problem parsing the X509 certificate.
|
||||
* @throws java.security.NoSuchAlgorithmException if there's a problem hashing the certificate.
|
||||
* @throws java.io.IOException If there's a problem parsing the signature data.
|
||||
*/
|
||||
private void processSigDataX509(final byte[] efiSigData)
|
||||
throws CertificateException, NoSuchAlgorithmException, IOException {
|
||||
|
||||
ByteArrayInputStream efiSigDataIS = new ByteArrayInputStream(efiSigData);
|
||||
ArrayList<UefiSignatureData> sigList = new ArrayList<UefiSignatureData>();
|
||||
spdmDevdcInfo += "";
|
||||
|
||||
// for now, hard-code the signature type for X509
|
||||
// in future with more test data, update this (potentially need to look at previous SPDM event)
|
||||
byte[] guid = HexUtils.hexStringToByteArray("A159C0A5E494A74A87B5AB155C2BF072");
|
||||
UefiGuid signatureType = new UefiGuid(guid);
|
||||
|
||||
int numberOfCerts = 0;
|
||||
boolean dataValid = true;
|
||||
String dataInvalidStatus = "Signature data validity is undetermined yet";
|
||||
while (efiSigDataIS.available() > 0) {
|
||||
UefiSignatureData tmpSigData = new UefiSignatureData(efiSigDataIS, signatureType);
|
||||
if (!tmpSigData.isValid()) {
|
||||
dataValid = false;
|
||||
dataInvalidStatus = tmpSigData.getStatus();
|
||||
break;
|
||||
}
|
||||
sigList.add(tmpSigData);
|
||||
numberOfCerts++;
|
||||
}
|
||||
spdmDevdcInfo += " Number of X509 Certs in UEFI Signature Data = " + numberOfCerts + "\n";
|
||||
int certCnt = 0;
|
||||
for (int i = 0; i < sigList.size(); i++) {
|
||||
certCnt++;
|
||||
spdmDevdcInfo += " Cert # " + certCnt + " of " + numberOfCerts + ": ------------------\n";
|
||||
UefiSignatureData certData = sigList.get(i);
|
||||
spdmDevdcInfo += certData.toString();
|
||||
}
|
||||
if (!dataValid) {
|
||||
spdmDevdcInfo += " *** Invalid UEFI Signature data encountered: " + dataInvalidStatus + "\n";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Print out all the interesting characteristics available on this UEFI Variable.
|
||||
*
|
||||
* @return human readable description of the UEFi variable.
|
||||
* @return human-readable description of the UEFi variable.
|
||||
*/
|
||||
public String toString() {
|
||||
StringBuilder efiVariable = new StringBuilder();
|
||||
|
||||
efiVariable.append("UEFI Variable Name: " + efiVarName + "\n");
|
||||
efiVariable.append("UEFI Variable GUID: " + uefiVarGuid.toString() + "\n");
|
||||
efiVariable.append(" UEFI Variable Name: " + efiVarName + "\n");
|
||||
efiVariable.append(" UEFI Variable GUID: " + uefiVarGuid.toString() + "\n");
|
||||
if (efiVarName != "") {
|
||||
efiVariable.append("UEFI Variable Contents => " + "\n");
|
||||
efiVariable.append(" UEFI Variable Contents => " + "\n");
|
||||
}
|
||||
String tmpName = "";
|
||||
if (efiVarName.contains("Boot00")) {
|
||||
@ -216,11 +273,9 @@ public class UefiVariable {
|
||||
case "KEK":
|
||||
case "db":
|
||||
case "dbx":
|
||||
break;
|
||||
case "devdb": // SPDM_DEVICE_POLICY and SPDM_DEVICE_AUTHORITY
|
||||
// (update when test patterns exist)
|
||||
efiVariable.append(" EV_EFI_SPDM_DEVICE_POLICY and EV_EFI_SPDM_DEVICE_AUTHORITY: " +
|
||||
"To be processed once more test patterns exist");
|
||||
case "devdc": // for now use devdb and devdc respectively
|
||||
// (update when more test patterns exist)
|
||||
break;
|
||||
case "Boot00":
|
||||
efiVariable.append(bootv.toString());
|
||||
@ -233,38 +288,43 @@ public class UefiVariable {
|
||||
break;
|
||||
default:
|
||||
if (!tmpName.isEmpty()) {
|
||||
efiVariable.append(String.format("Data not provided for "
|
||||
efiVariable.append(String.format(" Data not provided for "
|
||||
+ "UEFI variable named %s ", tmpName));
|
||||
} else {
|
||||
efiVariable.append("Data not provided ");
|
||||
efiVariable.append(" Data not provided ");
|
||||
}
|
||||
}
|
||||
|
||||
// Signature List output (if there are any Signature Lists)
|
||||
if (certSuperList.size() > 0){
|
||||
if (certSuperList.size() > 0) {
|
||||
efiVariable.append("Number of UEFI Signature Lists = " + certSuperList.size() + "\n");
|
||||
int certSuperListCnt = 1;
|
||||
for (UefiSignatureList uefiSigList : certSuperList) {
|
||||
efiVariable.append("UEFI Signature List # " + certSuperListCnt++ + " of "
|
||||
+ certSuperList.size() + ": ------------------\n");
|
||||
efiVariable.append(uefiSigList.toString());
|
||||
}
|
||||
}
|
||||
int certSuperListCnt = 1;
|
||||
for (UefiSignatureList uefiSigList : certSuperList) {
|
||||
efiVariable.append("UEFI Signature List # " + certSuperListCnt++ + " of " +
|
||||
certSuperList.size() + ":\n");
|
||||
efiVariable.append(uefiSigList.toString());
|
||||
}
|
||||
if(invalidSignatureListEncountered) {
|
||||
if (invalidSignatureListEncountered) {
|
||||
efiVariable.append(invalidSignatureListStatus);
|
||||
efiVariable.append("*** Encountered invalid Signature Type - " +
|
||||
"Stopped processing of this event data\n");
|
||||
efiVariable.append("*** Encountered invalid Signature Type - "
|
||||
+ "Stopped processing of this event data\n");
|
||||
}
|
||||
|
||||
// Signature Data output (if there is a Signature Data)
|
||||
if (!spdmDevdcInfo.isEmpty()) {
|
||||
efiVariable.append(spdmDevdcInfo);
|
||||
}
|
||||
|
||||
return efiVariable.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves human readable description from a Certificate.
|
||||
* Retrieves human-readable description from a Certificate.
|
||||
*
|
||||
* @param data byte[] holding the certificate.
|
||||
* @param offset offset to start of the certificate within the byte array.
|
||||
* @return human readable description of a certificate.
|
||||
* @return human-readable description of a certificate.
|
||||
*/
|
||||
public String printCert(final byte[] data, final int offset) {
|
||||
String certInfo = "";
|
||||
|
@ -1,5 +1,9 @@
|
||||
package hirs.tcg_eventlog;
|
||||
|
||||
import hirs.utils.HexUtils;
|
||||
import hirs.utils.tpm.eventlog.TCGEventLog;
|
||||
import hirs.utils.tpm.eventlog.TpmPcrEvent;
|
||||
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.Charset;
|
||||
@ -12,10 +16,6 @@ import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
|
||||
import hirs.utils.tpm.eventlog.TCGEventLog;
|
||||
import hirs.utils.tpm.eventlog.TpmPcrEvent;
|
||||
import hirs.utils.HexUtils;
|
||||
|
||||
import static hirs.utils.tpm.eventlog.uefi.UefiConstants.FILESTATUS_FROM_CODE;
|
||||
import static hirs.utils.tpm.eventlog.uefi.UefiConstants.FILESTATUS_NOT_ACCESSIBLE;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user