From 715e6599b9b0cf0c281148821b67723a2d405eaf Mon Sep 17 00:00:00 2001 From: iadgovuser58 <124906646+iadgovuser58@users.noreply.github.com> Date: Mon, 22 Apr 2024 14:35:58 -0400 Subject: [PATCH] spdm processing - output is complete --- .../hirs/utils/tpm/eventlog/TpmPcrEvent.java | 8 +- .../events/DeviceSecurityEventData.java | 4 +- .../events/DeviceSecurityEventDataBase.java | 4 + .../events/DeviceSecurityEventDataHeader.java | 88 ++++++++----- .../DeviceSecurityEventDataHeaderBase.java | 121 +++++++----------- .../hirs/utils/tpm/eventlog/spdm/SpdmHa.java | 3 +- .../tpm/eventlog/spdm/SpdmMeasurement.java | 105 ++++++++++++++- .../eventlog/spdm/SpdmMeasurementBlock.java | 64 +++++++-- 8 files changed, 273 insertions(+), 124 deletions(-) diff --git a/HIRS_Utils/src/main/java/hirs/utils/tpm/eventlog/TpmPcrEvent.java b/HIRS_Utils/src/main/java/hirs/utils/tpm/eventlog/TpmPcrEvent.java index f921ee4d..c6027fbf 100644 --- a/HIRS_Utils/src/main/java/hirs/utils/tpm/eventlog/TpmPcrEvent.java +++ b/HIRS_Utils/src/main/java/hirs/utils/tpm/eventlog/TpmPcrEvent.java @@ -376,6 +376,13 @@ public class TpmPcrEvent { case EvConstants.EV_EFI_HCRTM_EVENT: break; case EvConstants.EV_EFI_SPDM_FIRMWARE_BLOB: + try { + sb.append(new EvEfiSpdmFirmwareBlob(eventContent).toString()); + } catch (UnsupportedEncodingException ueEx) { + log.error(ueEx); + sb.append(ueEx.toString()); + } + break; default: sb.append("Unknown Event found\n"); } @@ -552,7 +559,6 @@ public class TpmPcrEvent { */ private static String eventString(final long event) { - System.out.println("XXXX " + event); if (event == EvConstants.EV_PREBOOT_CERT) { return "EV_PREBOOT_CERT"; } else if (event == EvConstants.EV_POST_CODE) { diff --git a/HIRS_Utils/src/main/java/hirs/utils/tpm/eventlog/events/DeviceSecurityEventData.java b/HIRS_Utils/src/main/java/hirs/utils/tpm/eventlog/events/DeviceSecurityEventData.java index 9e3098ab..f7c4d8b6 100644 --- a/HIRS_Utils/src/main/java/hirs/utils/tpm/eventlog/events/DeviceSecurityEventData.java +++ b/HIRS_Utils/src/main/java/hirs/utils/tpm/eventlog/events/DeviceSecurityEventData.java @@ -3,6 +3,8 @@ package hirs.utils.tpm.eventlog.events; import lombok.Getter; +import java.io.UnsupportedEncodingException; + public class DeviceSecurityEventData extends DeviceSecurityEventDataBase { /** @@ -16,7 +18,7 @@ public class DeviceSecurityEventData extends DeviceSecurityEventDataBase { * * @param dSEDbytes byte array holding the DeviceSecurityEventData. */ - public DeviceSecurityEventData(final byte[] dSEDbytes) { + public DeviceSecurityEventData(final byte[] dSEDbytes) throws UnsupportedEncodingException { super(dSEDbytes); dsedHeader = new DeviceSecurityEventDataHeader(dSEDbytes); } diff --git a/HIRS_Utils/src/main/java/hirs/utils/tpm/eventlog/events/DeviceSecurityEventDataBase.java b/HIRS_Utils/src/main/java/hirs/utils/tpm/eventlog/events/DeviceSecurityEventDataBase.java index 3e7b8a1f..46f3bdba 100644 --- a/HIRS_Utils/src/main/java/hirs/utils/tpm/eventlog/events/DeviceSecurityEventDataBase.java +++ b/HIRS_Utils/src/main/java/hirs/utils/tpm/eventlog/events/DeviceSecurityEventDataBase.java @@ -44,6 +44,10 @@ import java.nio.charset.StandardCharsets; * 2. Digest of 48 bytes * 3. Event content defined as DEVICE_SECURITY_EVENT_DATA Struct. * 4. First 16 bytes of the structure header is an ASCII "SPDM Device Sec" + *

+ * 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. */ public abstract class DeviceSecurityEventDataBase { diff --git a/HIRS_Utils/src/main/java/hirs/utils/tpm/eventlog/events/DeviceSecurityEventDataHeader.java b/HIRS_Utils/src/main/java/hirs/utils/tpm/eventlog/events/DeviceSecurityEventDataHeader.java index 5073a1d2..955a353c 100644 --- a/HIRS_Utils/src/main/java/hirs/utils/tpm/eventlog/events/DeviceSecurityEventDataHeader.java +++ b/HIRS_Utils/src/main/java/hirs/utils/tpm/eventlog/events/DeviceSecurityEventDataHeader.java @@ -6,63 +6,81 @@ import hirs.utils.tpm.eventlog.spdm.SpdmMeasurementBlock; import hirs.utils.tpm.eventlog.uefi.UefiConstants; import lombok.Getter; +import java.io.UnsupportedEncodingException; + + +/** + * Class to process the DEVICE_SECURITY_EVENT_DATA_HEADER. + * DEVICE_SECURITY_EVENT_DATA_HEADER contains the measurement(s) and hash algorithm identifier + * returned by the SPDM "GET_MEASUREMENTS" function. + * + * HEADERS defined by PFP v1.06 Rev 52: + *

+ * typedef struct tdDEVICE_SECURITY_EVENT_DATA_HEADER { + * UINT8 Signature[16]; + * UINT16 Version; + * UINT16 Length; + * UINT32 SpdmHashAlg; + * UINT32 DeviceType; + * SPDM_MEASUREMENT_BLOCK SpdmMeasurementBlock; + * UINT64 DevicePathLength; + * UNIT8 DevicePath[DevicePathLength] + * } DEVICE_SECURITY_EVENT_DATA_HEADER; + *

+ * Assumption: there is only 1 SpdmMeasurementBlock per event. Need more test patterns to verify. + */ public class DeviceSecurityEventDataHeader extends DeviceSecurityEventDataHeaderBase { - /** ----------- Variables specific to Header Type 1 ----------- - // /** - // * Type Header 1 event data length. - // */ -// @Getter -// private String h1Length = ""; /** - * Type Header 1 SPDM hash algorithm. + * Event data length. */ @Getter - private String h1SpdmHashAlgo = ""; -// /** -// * Type Header 1 SPDM Measurement Block list. -// */ -// private List h1SpdmMeasurementBlockList; + private int length = 0; /** - * Type Header 1 SPDM Measurement Block. + * SPDM hash algorithm. */ - private SpdmMeasurementBlock h1SpdmMeasurementBlock; + @Getter + private int spdmHashAlgo = -1; + /** + * SPDM Measurement Block list. -implement this if there can be multiple SPDM blocks in one event + */ + //private List spdmMeasurementBlockList; + /** + * SPDM Measurement Block. + */ + private SpdmMeasurementBlock spdmMeasurementBlock; - public DeviceSecurityEventDataHeader(final byte[] dSEDbytes) { + public DeviceSecurityEventDataHeader(final byte[] dSEDbytes) throws UnsupportedEncodingException { super(dSEDbytes); byte[] lengthBytes = new byte[UefiConstants.SIZE_2]; System.arraycopy(dSEDbytes, 18, lengthBytes, 0, UefiConstants.SIZE_2); - int h1Length = HexUtils.leReverseInt(lengthBytes); + length = HexUtils.leReverseInt(lengthBytes); byte[] spdmHashAlgoBytes = new byte[UefiConstants.SIZE_4]; System.arraycopy(dSEDbytes, UefiConstants.OFFSET_20, spdmHashAlgoBytes, 0, UefiConstants.SIZE_4); - int h1SpdmHashAlgoInt = HexUtils.leReverseInt(spdmHashAlgoBytes); - h1SpdmHashAlgo = SpdmHa.tcgAlgIdToString(h1SpdmHashAlgoInt); + spdmHashAlgo = HexUtils.leReverseInt(spdmHashAlgoBytes); -// byte[] deviceTypeBytes = new byte[UefiConstants.SIZE_4]; -// System.arraycopy(dSEDbytes, UefiConstants.OFFSET_24, deviceTypeBytes, 0, -// UefiConstants.SIZE_4); -// int deviceTypeInt = HexUtils.leReverseInt(deviceTypeBytes); -// deviceType = deviceTypeToString(deviceTypeInt); - - // For each measurement block, create a SpdmMeasurementBlock object (can there be many blocks ?) + extractDeviceType(dSEDbytes, 24); // get the size of the SPDM Measurement Block byte[] sizeOfSpdmMeasBlockBytes = new byte[UefiConstants.SIZE_2]; System.arraycopy(dSEDbytes, 30, sizeOfSpdmMeasBlockBytes, 0, UefiConstants.SIZE_2); int sizeOfSpdmMeas = HexUtils.leReverseInt(sizeOfSpdmMeasBlockBytes); - int sizeOfSpdmMeasBlock = sizeOfSpdmMeas + 4; + int sizeOfSpdmMeasBlock = sizeOfSpdmMeas + 4; // header is 4 bytes // extract the bytes from the SPDM Measurement Block byte[] spdmMeasBlockBytes = new byte[sizeOfSpdmMeasBlock]; System.arraycopy(dSEDbytes, 28, spdmMeasBlockBytes, 0, sizeOfSpdmMeasBlock); - h1SpdmMeasurementBlock = new SpdmMeasurementBlock(spdmMeasBlockBytes); + spdmMeasurementBlock = new SpdmMeasurementBlock(spdmMeasBlockBytes); + + + // (can there be many >1 spdm block per event ?) // byte[] algorithmIDBytes = new byte[UefiConstants.SIZE_2]; // int algLocation = UefiConstants.SIZE_28; @@ -72,11 +90,9 @@ public class DeviceSecurityEventDataHeader extends DeviceSecurityEventDataHeader // String alg = TcgTpmtHa.tcgAlgIdToString(HexUtils.leReverseInt(algorithmIDBytes)); // algList.add(alg); // } -// if ((algList.size() == 1) && (algList.get(0).compareTo("SHA1") == 0)) { -// cryptoAgile = false; -// } else { -// cryptoAgile = true; -// } + + int devPathLenStartByte = 28 + sizeOfSpdmMeasBlock; + extractDevicePath(dSEDbytes, devPathLenStartByte); } @@ -88,8 +104,12 @@ public class DeviceSecurityEventDataHeader extends DeviceSecurityEventDataHeader */ public String toString() { String dsedHeaderInfo = ""; - dsedHeaderInfo += "\n SPDM hash algorithm = " + h1SpdmHashAlgo; - dsedHeaderInfo += "\n SPDM Measurement Block " + h1SpdmMeasurementBlock.toString(); + + dsedHeaderInfo += headerBaseToString(); + String spdmHashAlgoStr = SpdmHa.tcgAlgIdToString(spdmHashAlgo); + dsedHeaderInfo += "\n SPDM Hash Algorithm = " + spdmHashAlgoStr; + dsedHeaderInfo += "\n SPDM Measurement Block:"; + dsedHeaderInfo += spdmMeasurementBlock.toString(); return dsedHeaderInfo; } diff --git a/HIRS_Utils/src/main/java/hirs/utils/tpm/eventlog/events/DeviceSecurityEventDataHeaderBase.java b/HIRS_Utils/src/main/java/hirs/utils/tpm/eventlog/events/DeviceSecurityEventDataHeaderBase.java index ee0ee8ba..763a163f 100644 --- a/HIRS_Utils/src/main/java/hirs/utils/tpm/eventlog/events/DeviceSecurityEventDataHeaderBase.java +++ b/HIRS_Utils/src/main/java/hirs/utils/tpm/eventlog/events/DeviceSecurityEventDataHeaderBase.java @@ -4,70 +4,45 @@ import hirs.utils.HexUtils; import hirs.utils.tpm.eventlog.spdm.SpdmHa; import hirs.utils.tpm.eventlog.spdm.SpdmMeasurementBlock; 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; /** - * Class to process the DEVICE_SECURITY_EVENT_DATA_HEADER or ..HEADER2 per PFP. + * Abstract class to process the DEVICE_SECURITY_EVENT_DATA_HEADER or ..HEADER2 per PFP. * 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. - * DEVICE_SECURITY_EVENT_DATA_HEADER contains the measurement(s) and hash algorithm identifier - * returned by the SPDM "GET_MEASUREMENTS" function. * - * HEADERS defined by PFP v1.06 Rev 52: + * HEADERS defined by PFP v1.06 Rev 52. + * The ** indicates fields that are common to both ..HEADER and ..HEADER2. *

* typedef struct tdDEVICE_SECURITY_EVENT_DATA_HEADER { - * UINT8 Signature[16]; - * UINT16 Version; + * UINT8 ** Signature[16]; + * UINT16 ** Version; * UINT16 Length; * UINT32 SpdmHashAlg; - * UINT32 DeviceType; + * UINT32 ** DeviceType; * SPDM_MEASUREMENT_BLOCK SpdmMeasurementBlock; - * UINT64 DevicePathLength; - * UNIT8 DevicePath[DevicePathLength] + * UINT64 ** DevicePathLength; + * UNIT8 ** DevicePath[DevicePathLength] * } DEVICE_SECURITY_EVENT_DATA_HEADER; *

* typedef struct tdDEVICE_SECURITY_EVENT_DATA_HEADER2 { - NOT IMPLEMENTED YET - * UINT8 Signature[16]; - * UINT16 Version; + * UINT8 ** Signature[16]; + * UINT16 ** Version; * UINT8 AuthState; * UINT8 Reserved; * UINT32 Length; - * UINT32 DeviceType; + * UINT32 ** DeviceType; * UINT32 SubHeaderType; * UINT32 SubHeaderLength; * UINT32 SubHeaderUID; - * UINT64 DevicePathLength; - * UNIT8 DevicePath[DevicePathLength] + * UINT64 ** DevicePathLength; + * UNIT8 ** DevicePath[DevicePathLength] * } DEVICE_SECURITY_EVENT_DATA_HEADER2; - * - * SPDM_MEASUREMENT_BLOCK and contents defined by SPDM v1.03, Sect 10.11.1, Table 53 and 54: - *

- * Measurement block format { - * Index 1 byte; - * MeasurementSpec 1 byte; - * MeasurementSize 2 bytes; - * Measurement bytes; - * } - *

- * DMTF measurement spec format { - * DMTFSpecMeasurementValueType 1 byte; - * DMTFSpecMeasurementValueSize 2 bytes; - * DMTFSpecMeasurementValue bytes; - * } - *

- * DMTFSpecMeasurementValueType[7] - * Indicates how bits [0:6] are represented - * Bit = 0: Digest - * Bit = 1: Raw bit stream - * DMTFSpecMeasurementValueType[6:0] - * Immutable ROM 0x0 - * Mutable firmware 0x1 - * Hardware configuration 0x2 - * Firmware configuration 0x3 - * etc. *

*/ public abstract class DeviceSecurityEventDataHeaderBase { @@ -98,22 +73,21 @@ public abstract class DeviceSecurityEventDataHeaderBase { * Device type. */ @Getter - private int deviceTypeId = -1; -// /** -// * Device type. -// */ -// @Getter -// private String deviceType = ""; + private int deviceType = -1; /** - * Device path length. + * UEFI Device Path Length. */ @Getter - private String devicePathLength = ""; + private int devicePathLength = 0; /** - * Device path. + * UEFI Device path. */ @Getter - private String devicePath = ""; + private UefiDevicePath devicePath = null; + /** + * Is the Device Path Valid. + */ + private boolean devicePathValid = false; /** * Device Security Event Data Device Type = no device type. @@ -155,32 +129,33 @@ public abstract class DeviceSecurityEventDataHeaderBase { } - public void extractDeviceTypeId(final byte[] dSEDbytes, int startByte) { + public void extractDeviceType(final byte[] dSEDbytes, int startByte) { // get the device type ID byte[] deviceTypeBytes = new byte[UefiConstants.SIZE_4]; System.arraycopy(dSEDbytes, startByte, deviceTypeBytes, 0, UefiConstants.SIZE_4); - deviceTypeId = HexUtils.leReverseInt(deviceTypeBytes); + deviceType = HexUtils.leReverseInt(deviceTypeBytes); } - public void extractDevicePathString(final byte[] dSEDbytes, int startByte) { + public void extractDevicePath(final byte[] dSEDbytes, int startByte) + throws UnsupportedEncodingException { // get the device path length byte[] devicePathLengthBytes = new byte[UefiConstants.SIZE_8]; System.arraycopy(dSEDbytes, startByte, devicePathLengthBytes, 0, UefiConstants.SIZE_8); - int deviceTypeLength = HexUtils.leReverseInt(devicePathLengthBytes); - - // TODO: how to interpret this?? i'ts not ascii + int devicePathLength = HexUtils.leReverseInt(devicePathLengthBytes); // get the device path - startByte = startByte + UefiConstants.SIZE_8; - byte[] devicePathBytes = new byte[UefiConstants.SIZE_16]; - System.arraycopy(dSEDbytes, startByte, devicePathBytes, 0, - deviceTypeLength); - - // TODO: store device path length + if (devicePathLength != 0) { + startByte = startByte + UefiConstants.SIZE_8; + byte[] devPathBytes = new byte[devicePathLength]; + System.arraycopy(dSEDbytes, startByte, devPathBytes, + 0, devicePathLength); + devicePath = new UefiDevicePath(devPathBytes); + devicePathValid = true; + } } /** @@ -213,22 +188,18 @@ public abstract class DeviceSecurityEventDataHeaderBase { * * @return a description of this event.. */ - public String toString() { + public String headerBaseToString() { String dsedHeaderInfo = ""; - dsedHeaderInfo += "\n SPDM Device"; - dsedHeaderInfo += "\n Device Type: " + deviceTypeToString(deviceTypeId); - dsedHeaderInfo += "\n Device Path: " + devicePath; + dsedHeaderInfo += "\n SPDM Device Type = " + deviceTypeToString(deviceType); + if (devicePathValid) { + dsedHeaderInfo += "\n SPDM Device Path =\n"; + dsedHeaderInfo += devicePath; + } + else { + dsedHeaderInfo += "\n SPDM Device Path = Uknown or invalid"; + } -// if (version.equals("0100")) { -// dsedHeaderInfo += "\n SPDM hash algorithm = " + h1SpdmHashAlgo; -// dsedHeaderInfo += "\n SPDM Device"; -// dsedHeaderInfo += "\n Device Type: " + deviceType; -// dsedHeaderInfo += "\n Device Path: " + devicePath; -// dsedHeaderInfo += "\n SPDM Measurement Block " + h1SpdmMeasurementBlock.toString(); -// } else if(version.equals("0200")) { -// dsedHeaderInfo = "tbd"; -// } return dsedHeaderInfo; } diff --git a/HIRS_Utils/src/main/java/hirs/utils/tpm/eventlog/spdm/SpdmHa.java b/HIRS_Utils/src/main/java/hirs/utils/tpm/eventlog/spdm/SpdmHa.java index ce6a2fb1..3195896f 100644 --- a/HIRS_Utils/src/main/java/hirs/utils/tpm/eventlog/spdm/SpdmHa.java +++ b/HIRS_Utils/src/main/java/hirs/utils/tpm/eventlog/spdm/SpdmHa.java @@ -5,8 +5,7 @@ import lombok.AccessLevel; import lombok.NoArgsConstructor; /** - * Class for defining constants referenced in the DMTF - * SPDM specification. + * Class for defining constants referenced in the DMTF SPDM specification. */ @NoArgsConstructor(access = AccessLevel.PRIVATE) public class SpdmHa { diff --git a/HIRS_Utils/src/main/java/hirs/utils/tpm/eventlog/spdm/SpdmMeasurement.java b/HIRS_Utils/src/main/java/hirs/utils/tpm/eventlog/spdm/SpdmMeasurement.java index 4dd82a4e..1555d4aa 100644 --- a/HIRS_Utils/src/main/java/hirs/utils/tpm/eventlog/spdm/SpdmMeasurement.java +++ b/HIRS_Utils/src/main/java/hirs/utils/tpm/eventlog/spdm/SpdmMeasurement.java @@ -1,13 +1,116 @@ package hirs.utils.tpm.eventlog.spdm; +import hirs.utils.HexUtils; +import lombok.AccessLevel; +import lombok.Getter; + +/** + * Class to process the SpdmMeasurement. + *

+ * Measurement, defined by SPDM v1.03, Sect 10.11.1, Table 54: + * DMTF measurement spec format { + * DMTFSpecMeasurementValueType 1 byte; + * DMTFSpecMeasurementValueSize 2 bytes; + * DMTFSpecMeasurementValue bytes; + * } + *

+ * DMTFSpecMeasurementValueType[7] + * Indicates how bits [0:6] are represented + * Bit = 0: Digest + * Bit = 1: Raw bit stream + * DMTFSpecMeasurementValueType[6:0] (see SPDM Spec, Table 55 "DMTFSpecMeasurementValueType[6:0]") + * Immutable ROM 0x0 + * Mutable firmware 0x1 + * Hardware configuration 0x2 + * Firmware configuration 0x3 + * etc. + *

+ */ public class SpdmMeasurement { + /** + * Measurement value type (such as mutable firmware, etc). + */ + @Getter + private int dmtfSpecMeasurementValueType = 0; + /** + * Measurement value (digest). + */ + @Getter + private byte[] dmtfSpecMeasurementValue = null; + + @Getter(value = AccessLevel.PROTECTED) + private byte[] digest = null; + public SpdmMeasurement(final byte[] spdmMeasBytes) { + byte[] dmtfSpecMeasurementValueTypeBytes = new byte[1]; + System.arraycopy(spdmMeasBytes, 0, dmtfSpecMeasurementValueTypeBytes, 0, + 1); + dmtfSpecMeasurementValueType = HexUtils.leReverseInt(dmtfSpecMeasurementValueTypeBytes); + + // in future, can crosscheck this value size + 3 with the spdm block MeasurementSize size + byte[] dmtfSpecMeasurementValueSizeBytes = new byte[2]; + System.arraycopy(spdmMeasBytes, 1, dmtfSpecMeasurementValueSizeBytes, 0, + 2); + int dmtfSpecMeasurementValueSize = HexUtils.leReverseInt(dmtfSpecMeasurementValueSizeBytes); + + dmtfSpecMeasurementValue = new byte[dmtfSpecMeasurementValueSize]; + System.arraycopy(spdmMeasBytes, 3, dmtfSpecMeasurementValue, 0, + dmtfSpecMeasurementValueSize); } + public String dmtfSpecMeasurementValueTypeToString(final int measValType) { + + String measValTypeStr; + switch (measValType) { + case 0: + measValTypeStr = "Immutable ROM"; + break; + case 1: + measValTypeStr = "Mutable firmware"; + break; + case 2: + measValTypeStr = "Hardware configuration"; + break; + case 3: + measValTypeStr = "Firmware configuration"; + break; + case 4: + measValTypeStr = "Freeform measurement manifest"; + break; + case 5: + measValTypeStr = "Structured representation of debug and device mode"; + break; + case 6: + measValTypeStr = "Mutable firmware's version number"; + break; + case 7: + measValTypeStr = "Mutable firmware's security verison number"; + break; + case 8: + measValTypeStr = "Hash-extended measurement"; + break; + case 9: + measValTypeStr = "Informational"; + break; + case 10: + measValTypeStr = "Structured measurement manifest"; + break; + default: + measValTypeStr = "Unknown or invalid DMTF Spec Measurement Value Type"; + } + return measValTypeStr; + } public String toString() { - return "TEMP TEST SpdmMeasurement"; + String spdmMeasInfo = ""; + + spdmMeasInfo += "\n SPDM Measurement Value Type = " + + dmtfSpecMeasurementValueTypeToString(dmtfSpecMeasurementValueType); + spdmMeasInfo += "\n SPDM Measurement Value = " + + HexUtils.byteArrayToHexString(dmtfSpecMeasurementValue); + + return spdmMeasInfo; } } diff --git a/HIRS_Utils/src/main/java/hirs/utils/tpm/eventlog/spdm/SpdmMeasurementBlock.java b/HIRS_Utils/src/main/java/hirs/utils/tpm/eventlog/spdm/SpdmMeasurementBlock.java index af8c95a4..ff2ac9ea 100644 --- a/HIRS_Utils/src/main/java/hirs/utils/tpm/eventlog/spdm/SpdmMeasurementBlock.java +++ b/HIRS_Utils/src/main/java/hirs/utils/tpm/eventlog/spdm/SpdmMeasurementBlock.java @@ -1,32 +1,76 @@ package hirs.utils.tpm.eventlog.spdm; +import hirs.utils.HexUtils; +import hirs.utils.tpm.eventlog.uefi.UefiConstants; import lombok.Getter; +/** + * Class to process the SpdmMeasurementBlock. + *

+ * Measurement block format, defined by SPDM v1.03, Sect 10.11.1, Table 53: + * Measurement block format { + * Index 1 byte; + * MeasurementSpec 1 byte; + * MeasurementSize 2 bytes; + * Measurement bytes; + * } + *

+ * Index: index of the measurement block, as there can be more than one + * MeasurementSpec: bit mask; the measurement specification that the requested Measurement follows + * See "MeasurementSpecificationSel" in Table 21. See Tables 29, 53, 54 + * Bit 0: DMTFmeasSpec, per Table 54 + * Bit 1-7: Reserved + * Measurement: the digest + */ public class SpdmMeasurementBlock { + /** + * Measurement block index, as an SPDM measurement exchange can contain several measurements. + */ + @Getter + private int index = 0; /** * Measurement Spec. */ @Getter - private String measurementSpec = ""; + private int measurementSpec = 0; /** - * Measurement value type (such as mutable firmware, etc). + * SPDM Measurement. */ - @Getter - private String dmtfSpecMeasurementValueType = ""; - /** - * Measurement value (digest). - */ - @Getter - private String dmtfSpecMeasurementValue = ""; + private SpdmMeasurement spdmMeasurement; public SpdmMeasurementBlock(final byte[] spdmMeasBlockBytes) { + byte[] indexBytes = new byte[1]; + System.arraycopy(spdmMeasBlockBytes, 0, indexBytes, 0, + 1); + index = HexUtils.leReverseInt(indexBytes); + byte[] measurementSpecBytes = new byte[1]; + System.arraycopy(spdmMeasBlockBytes, 1, measurementSpecBytes, 0, + 1); + measurementSpec = HexUtils.leReverseInt(measurementSpecBytes); + + // in future, can crosscheck this measurement size with the MeasurementSpec hash alg size + byte[] measurementSizeBytes = new byte[2]; + System.arraycopy(spdmMeasBlockBytes, 2, measurementSizeBytes, 0, + 2); + int measurementSize = HexUtils.leReverseInt(measurementSizeBytes); + + byte[] measurementBytes = new byte[measurementSize]; + System.arraycopy(spdmMeasBlockBytes, 4, measurementBytes, 0, + measurementSize); + spdmMeasurement = new SpdmMeasurement(measurementBytes); } public String toString() { - return "TEMP TEST spdmMeasBlockBytes"; + String spdmMeasBlockInfo = ""; + + spdmMeasBlockInfo += "\n Index = " + index; + spdmMeasBlockInfo += "\n MeasurementSpec = " + measurementSpec; + spdmMeasBlockInfo += spdmMeasurement.toString(); + + return spdmMeasBlockInfo; } }