working SPDM NvIndex and CertChain

This commit is contained in:
iadgovuser58 2024-07-18 17:37:10 -04:00
parent f1a22c7cc4
commit 602fd88e53
13 changed files with 245 additions and 58 deletions

View File

@ -1,13 +1,8 @@
package hirs.utils.tpm.eventlog.events;
import hirs.utils.tpm.eventlog.spdm.SpdmMeasurementBlock;
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.
@ -81,10 +76,10 @@ public abstract class DeviceSecurityEvent {
*/
public void instantiateDeviceContext(final byte[] dsedDeviceContextBytes) {
if (deviceType == DEVICE_TYPE_NONE) {
if (deviceType == DeviceSecurityEventDataDeviceContext.DEVICE_TYPE_NONE) {
deviceContextInfo = "\n No Device Context (indicated by device type value of 0";
}
else if (deviceType == DEVICE_TYPE_PCI) {
else if (deviceType == DeviceSecurityEventDataDeviceContext.DEVICE_TYPE_PCI) {
try {
dsedDevContext
= new DeviceSecurityEventDataPciContext(dsedDeviceContextBytes);
@ -94,7 +89,7 @@ public abstract class DeviceSecurityEvent {
deviceContextInfo = " Could not interpret Device Context info";
}
}
else if (deviceType == DEVICE_TYPE_USB) {
else if (deviceType == DeviceSecurityEventDataDeviceContext.DEVICE_TYPE_USB) {
// dsedDevContext
// = new DeviceSecurityEventDataUsbContext(dsedDeviceContextBytes);
// deviceContextInfo = dsedDevContext.toString();

View File

@ -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.
@ -65,26 +59,35 @@ public class DeviceSecurityEventData2 extends DeviceSecurityEvent {
int subHeaderType = dsedHeader2.getSubHeaderType();
int subHeaderLength = dsedHeader2.getSubHeaderLength();
subHeaderInfo = "\nSub header type: " + subHeaderType;
subHeaderInfo = "\n Sub header type: "
+ DeviceSecurityEventDataSubHeader.subheaderTypeToString(subHeaderType);
byte[] dsedSubHeaderBytes = new byte[subHeaderLength];
System.arraycopy(dsedBytes, dsedHeaderLength, dsedSubHeaderBytes, 0, subHeaderLength);
if (subHeaderType == SUBHEADERTYPE_MEAS_BLOCK) {
if (subHeaderType == DeviceSecurityEventDataSubHeader.SUBHEADERTYPE_MEAS_BLOCK) {
try {
dsedSubHeader = new DeviceSecurityEventDataSubHeaderSpdmMeasurementBlock(dsedSubHeaderBytes);
dsedSubHeader =
new DeviceSecurityEventDataSubHeaderSpdmMeasurementBlock(dsedSubHeaderBytes);
subHeaderInfo += dsedSubHeader.toString();
}
catch(NullPointerException e) {
subHeaderInfo = " Could not interpret Sub header info";
subHeaderInfo = "\n Could not interpret Sub header info for SPDM measurment block";
}
}
else if (subHeaderType == SUBHEADERTYPE_CERT_CHAIN) {
// dsedSubHeader = new DeviceSecurityEventDataSubHeaderCertChain();
subHeaderInfo += " Cert chain to be implemented ";
else if (subHeaderType == DeviceSecurityEventDataSubHeader.SUBHEADERTYPE_CERT_CHAIN) {
subHeaderInfo += "\n Cert chain to be implemented ";
try {
dsedSubHeader =
new DeviceSecurityEventDataSubHeaderCertChain(dsedSubHeaderBytes);
subHeaderInfo += dsedSubHeader.toString();
}
catch(NullPointerException e) {
subHeaderInfo = "\n Could not interpret Sub header info for SPDM measurement block";
}
}
else {
subHeaderInfo += " Sub header type unknown";
subHeaderInfo += "\n Sub header type unknown";
}
int dsedDevContextStartByte = dsedHeaderLength + subHeaderLength;

View File

@ -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.
*

View File

@ -5,11 +5,8 @@ import hirs.utils.tpm.eventlog.spdm.SpdmHa;
import hirs.utils.tpm.eventlog.spdm.SpdmMeasurementBlock;
import hirs.utils.tpm.eventlog.uefi.UefiConstants;
import lombok.Getter;
import org.apache.commons.lang3.ObjectUtils;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
/**
* Class to process the DEVICE_SECURITY_EVENT_DATA_HEADER.

View File

@ -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
@ -81,15 +79,6 @@ public class DeviceSecurityEventDataHeader2 extends DeviceSecurityEventHeader {
* Auth state - device is not an SPDM-capable device
*/
public static final int AUTH_NO_SPDM = 0xFF;
/**
* Sub header type - SPDM measurement block
*/
public static final int SUBHEADERTYPE_MEAS_BLOCK = 0;
/**
* Sub header type - SPDM cert chain
*/
public static final int SUBHEADERTYPE_CERT_CHAIN = 1;
public DeviceSecurityEventDataHeader2(final byte[] dsedBytes) {

View File

@ -14,7 +14,35 @@ 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;
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";
}
}
}

View File

@ -0,0 +1,80 @@
package hirs.utils.tpm.eventlog.events;
import hirs.utils.HexUtils;
import hirs.utils.tpm.eventlog.spdm.SpdmMeasurementBlock;
import lombok.Getter;
import java.io.ByteArrayInputStream;
import java.util.ArrayList;
/**
* 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>
*/
public class DeviceSecurityEventDataSubHeaderCertChain extends DeviceSecurityEventDataSubHeader{
/**
* SPDM version.
*/
@Getter
private int spdmVersion = 0;
/**
* SPDM slot ID.
*/
@Getter
private int spdmLotId = 0;
/**
* SPDM base hash algorithm.
*/
@Getter
private int spdmBaseHashAlgo = -1;
/**
* DeviceSecurityEventDataSubHeaderCertChain Constructor.
*
* @param dsedSubHBytes byte array holding the DeviceSecurityEventDataSubHeaderSpdmMeasurementBlock.
*/
public DeviceSecurityEventDataSubHeaderCertChain(final byte[] dsedSubHBytes) {
spdmMeasurementBlockList = new ArrayList<>();
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);
spdmLotId = 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);
ByteArrayInputStream spdmMeasurementBlockListData =
new ByteArrayInputStream(spdmMeasurementBlockListBytes);
while (spdmMeasurementBlockListData.available() > 0) {
SpdmMeasurementBlock spdmMeasurementBlock;
spdmMeasurementBlock = new SpdmMeasurementBlock(spdmMeasurementBlockListData);
spdmMeasurementBlockList.add(spdmMeasurementBlock);
}
}
}

View File

@ -6,7 +6,6 @@ import hirs.utils.tpm.eventlog.spdm.SpdmMeasurementBlock;
import lombok.Getter;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
@ -47,7 +46,7 @@ public class DeviceSecurityEventDataSubHeaderSpdmMeasurementBlock extends Device
private List<SpdmMeasurementBlock> spdmMeasurementBlockList;
/**
* DeviceSecurityEventDataHeader Constructor.
* DeviceSecurityEventDataSubHeaderSpdmMeasurementBlock Constructor.
*
* @param dsedSubHBytes byte array holding the DeviceSecurityEventDataSubHeaderSpdmMeasurementBlock.
*/

View File

@ -89,20 +89,6 @@ public abstract class DeviceSecurityEventHeader {
*/
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.
*/
@ -187,11 +173,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";

View File

@ -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);

View File

@ -0,0 +1,98 @@
package hirs.utils.tpm.eventlog.spdm;
import hirs.utils.HexUtils;
import lombok.Getter;
import java.io.ByteArrayInputStream;
import java.io.IOException;
/**
* Class to process the SpdmCertificateChain.
* <p>
* Certificate chain format, defined by SPDM v1.03, Sect 10.6.1, Table 33:
* Certificate chain format {
* Length 1 byte;
* 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.
* 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.
*/
@Getter
private int length = 0;
/**
* Root hash.
*/
private byte[] rootHash = null;
/**
* Certificates.
*/
// private SpdmMeasurement spdmMeasurement;
/**
* Error reading SPDM Cert Chain.
*/
private boolean spdmCertificateChainReadError = false;
/**
* SpdmMeasurementBlock Constructor.
*
* @param spdmMeasBlocks byte array holding the SPDM Measurement Block bytes.
*/
public SpdmCertificateChain(final ByteArrayInputStream spdmMeasBlocks) {
try {
byte[] indexBytes = new byte[1];
spdmMeasBlocks.read(indexBytes);
index = HexUtils.leReverseInt(indexBytes);
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);
byte[] measurementBytes = new byte[measurementSize];
spdmMeasBlocks.read(measurementBytes);
spdmMeasurement = new SpdmMeasurement(measurementBytes);
} catch (IOException ioEx) {
spdmMeasurementBlockReadError = true;
}
}
/**
* Returns a human-readable description of the data within 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();
// }
//
// return spdmMeasBlockInfo;
// }
}

View File

@ -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

View File

@ -83,7 +83,7 @@ public class SpdmMeasurementBlock {
/**
* 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() {