diff --git a/HIRS_Utils/src/main/java/hirs/tpm/eventlog/events/EvEfiHandoffTable.java b/HIRS_Utils/src/main/java/hirs/tpm/eventlog/events/EvEfiHandoffTable.java index a87702c5..23dac975 100644 --- a/HIRS_Utils/src/main/java/hirs/tpm/eventlog/events/EvEfiHandoffTable.java +++ b/HIRS_Utils/src/main/java/hirs/tpm/eventlog/events/EvEfiHandoffTable.java @@ -1,43 +1,53 @@ - package hirs.tpm.eventlog.events; - -import java.util.ArrayList; +package hirs.tpm.eventlog.events; import hirs.tpm.eventlog.uefi.UefiConstants; import hirs.tpm.eventlog.uefi.UefiGuid; import hirs.utils.HexUtils; import java.math.BigInteger; +import java.nio.file.Path; +import java.util.ArrayList; -/** Class to process the PC Client Firmware profile defined EV_EFI_HANDOFF_TABLES event. +/** + * Class to process the PC Client Firmware profile defined EV_EFI_HANDOFF_TABLES event. * The Event data holds a structure called UEFI_HANDOFF_TABLE_POINTERS: - * - * tdUEFI_HANDOFF_TABLE_POINTERS { - * UINT64 NumberOfTables; - * UEFI_CONFIGURATION_TABLE TableEntry[NumberOfTables]; - * }UEFI_HANDOFF_TABLE_POINTERS; - * + *

+ * tdUEFI_HANDOFF_TABLE_POINTERS { + * UINT64 NumberOfTables; + * UEFI_CONFIGURATION_TABLE TableEntry[NumberOfTables]; + * }UEFI_HANDOFF_TABLE_POINTERS; + *

* The UEFI_CONFIGURATION_TABLE id defined in the UEFI spec as: - * - * typedef struct{ - * EFI_GUID VendorGuid; - * VOID *VendorTable; - * } EFI_CONFIGURATION_TABLE; + *

+ * typedef struct{ + * EFI_GUID VendorGuid; + * VOID *VendorTable; + * } EFI_CONFIGURATION_TABLE; * Where the defines * VendorGuid: The 128-bit GUID value that uniquely identifies the system configuration table. * VendorTable: A pointer to the table associated with VendorGuid. - * Section 4.6 of the UEFI spec has a listing of some of the industry defined - * standard that define the particular table. + * Section 4.6 of the UEFI spec has a listing of some of the industry defined + * standard that define the particular table. */ public class EvEfiHandoffTable { - /** Number of Tables. */ + /** + * Number of Tables. + */ private int tableCount = 0; - /** List of Vendor GUIDs. */ + /** + * List of Vendor GUIDs. + */ private ArrayList vendorGuids = new ArrayList(); - /** List of Vendors. */ + /** + * List of Vendors. + */ private ArrayList vendorTables = new ArrayList(); + private Path vendorPathString; + /** * EvEFIHandoffTable constructor. + * * @param tpmEventData byte array holding the Handoff table data. */ public EvEfiHandoffTable(final byte[] tpmEventData) { @@ -53,56 +63,87 @@ public class EvEfiHandoffTable { vendorGuids.add(getNextGUID(tpmEventData, offset)); vendorTables.add(getNextTable(tpmEventData, offset + UefiConstants.OFFSET_16)); offset += UefiConstants.OFFSET_24; - } + } } - /** - * Return the number of EFI configuration tables covered in this event. - * @return number of EFI configuration tables. + /** + * EvEFIHandoffTable constructor. + * + * @param tpmEventData byte array holding the Handoff table data. + * @param vendorPathString the string for the vendor file + */ + public EvEfiHandoffTable(final byte[] tpmEventData, final Path vendorPathString) { + // Get NumberOfTables from the EventData + byte[] count = new byte[UefiConstants.SIZE_8]; + System.arraycopy(tpmEventData, 0, count, 0, UefiConstants.SIZE_8); + byte[] bigEndCount = HexUtils.leReverseByte(count); + BigInteger countInt = new BigInteger(bigEndCount); + tableCount = countInt.intValue(); + this.vendorPathString = vendorPathString; + // process each UEFI_CONFIGURATION_TABLE table + int offset = UefiConstants.OFFSET_8; + for (int tables = 0; tables < tableCount; tables++) { + vendorGuids.add(getNextGUID(tpmEventData, offset)); + vendorTables.add(getNextTable(tpmEventData, offset + UefiConstants.OFFSET_16)); + offset += UefiConstants.OFFSET_24; + } + } + + /** + * Return the number of EFI configuration tables covered in this event. + * + * @return number of EFI configuration tables. */ public int getNumberOfTables() { - return tableCount; + return tableCount; } /** * Returns the next GUI in the table. + * * @param eventData byte array holding the guids. - * @param offset offset to the guid. + * @param offset offset to the guid. * @return Vendor Guid */ private UefiGuid getNextGUID(final byte[] eventData, final int offset) { byte[] guid = new byte[UefiConstants.SIZE_16]; System.arraycopy(eventData, offset, guid, 0, UefiConstants.SIZE_16); - return new UefiGuid(guid); + if (vendorPathString == null || vendorPathString.toString().isEmpty()) { + return new UefiGuid(guid); + } else { + return new UefiGuid(guid, vendorPathString); } + } /** * Copies the next table to a new array. + * * @param eventData byte array holding the next table. - * @param offset offset within the table to fond the data. + * @param offset offset within the table to fond the data. * @return a byte array holding the new table. */ - private byte[] getNextTable(final byte[] eventData, final int offset) { + private byte[] getNextTable(final byte[] eventData, final int offset) { byte[] table = new byte[UefiConstants.SIZE_8]; System.arraycopy(eventData, offset, table, 0, UefiConstants.SIZE_8); return table; - } + } - /** - * Returns a human readable description of the hand off tables. - * @return a human readable description. - */ - public String toString() { - StringBuilder tableInfo = new StringBuilder(); - tableInfo.append("Number of UEFI_CONFIGURATION_TABLEs = " + tableCount + "\n"); - for (int i = 0; i < tableCount; i++) { - UefiGuid currentGuid = vendorGuids.get(i); - tableInfo.append(" Table " + i + ": " + currentGuid.toString()); - tableInfo.append(" UEFI industry standard table type = " - + currentGuid.getVendorTableReference() + "\n"); - tableInfo.append(" VendorTable " + i + " address: " - + HexUtils.byteArrayToHexString(vendorTables.get(i))); - } - return tableInfo.toString(); + /** + * Returns a human readable description of the hand off tables. + * + * @return a human readable description. + */ + public String toString() { + StringBuilder tableInfo = new StringBuilder(); + tableInfo.append("Number of UEFI_CONFIGURATION_TABLEs = " + tableCount + "\n"); + for (int i = 0; i < tableCount; i++) { + UefiGuid currentGuid = vendorGuids.get(i); + tableInfo.append(" Table " + i + ": " + currentGuid.toString()); + tableInfo.append(" UEFI industry standard table type = " + + currentGuid.getVendorTableReference() + "\n"); + tableInfo.append(" VendorTable " + i + " address: " + + HexUtils.byteArrayToHexString(vendorTables.get(i))); + } + return tableInfo.toString(); } } diff --git a/HIRS_Utils/src/main/java/hirs/tpm/eventlog/uefi/UefiGuid.java b/HIRS_Utils/src/main/java/hirs/tpm/eventlog/uefi/UefiGuid.java index c67031ac..98292b3b 100644 --- a/HIRS_Utils/src/main/java/hirs/tpm/eventlog/uefi/UefiGuid.java +++ b/HIRS_Utils/src/main/java/hirs/tpm/eventlog/uefi/UefiGuid.java @@ -1,14 +1,14 @@ package hirs.tpm.eventlog.uefi; +import com.eclipsesource.json.JsonObject; +import hirs.utils.HexUtils; +import hirs.utils.JsonUtils; + import java.math.BigInteger; import java.nio.file.FileSystems; import java.nio.file.Path; import java.util.UUID; -import com.eclipsesource.json.JsonObject; -import hirs.utils.HexUtils; -import hirs.utils.JsonUtils; - /** * Class to process GUID per the UEFI specification * GUIDs are essentially UUID as defined by RFC-1422, however Microsoft refers to GUIDS. @@ -47,6 +47,20 @@ public class UefiGuid { uefiVendorRef = JsonUtils.getSpecificJsonObject(JSON_PATH, "VendorTable"); } + /** + * UefiGUID constructor. + * + * @param guidBytes byte array holding a valid guid. + * @param vendorPathString string path for vendor + */ + public UefiGuid(final byte[] guidBytes, final Path vendorPathString) { + guid = new byte[UefiConstants.SIZE_16]; + System.arraycopy(guidBytes, 0, guid, 0, UefiConstants.SIZE_16); + uuid = processGuid(guidBytes); + uefiVendorRef = JsonUtils.getSpecificJsonObject(vendorPathString, + "VendorTable"); + } + /** * Converts a GUID with a byte array to a RFC-1422 UUID object. * Assumes a MS format and converts to Big Endian format used by most others , including Linux diff --git a/HIRS_Utils/src/test/java/hirs/data/persist/certificate/attributes/ComponentClassTest.java b/HIRS_Utils/src/test/java/hirs/data/persist/certificate/attributes/ComponentClassTest.java index c42bdccc..9e60b91e 100644 --- a/HIRS_Utils/src/test/java/hirs/data/persist/certificate/attributes/ComponentClassTest.java +++ b/HIRS_Utils/src/test/java/hirs/data/persist/certificate/attributes/ComponentClassTest.java @@ -20,8 +20,9 @@ public class ComponentClassTest { @Test public void testGetComponentNoneUNK() throws URISyntaxException { String componentIdentifier = "00000001"; - ComponentClass instance = new ComponentClass("TCG", Paths.get(this.getClass() - .getResource(JSON_FILE).toURI()), componentIdentifier); + ComponentClass instance = new ComponentClass("TCG", + Paths.get(this.getClass().getResource(JSON_FILE).toURI()), + componentIdentifier); String resultCategory = instance.getCategory(); String resultComponent = instance.getComponent(); Assert.assertEquals(resultComponent, "Unknown"); diff --git a/HIRS_Utils/src/test/java/hirs/tpm/eventlog/events/TCGEventLogEventsTest.java b/HIRS_Utils/src/test/java/hirs/tpm/eventlog/events/TCGEventLogEventsTest.java index 828051d0..7740ec91 100644 --- a/HIRS_Utils/src/test/java/hirs/tpm/eventlog/events/TCGEventLogEventsTest.java +++ b/HIRS_Utils/src/test/java/hirs/tpm/eventlog/events/TCGEventLogEventsTest.java @@ -1,10 +1,9 @@ package hirs.tpm.eventlog.events; -import java.io.IOException; -import java.security.NoSuchAlgorithmException; -import java.security.cert.CertificateException; -import java.util.ArrayList; - +import hirs.tpm.eventlog.TCGEventLogTest; +import hirs.tpm.eventlog.uefi.UefiGuid; +import hirs.tpm.eventlog.uefi.UefiPartition; +import hirs.utils.HexUtils; import org.apache.commons.io.IOUtils; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -13,25 +12,28 @@ import org.testng.annotations.AfterClass; import org.testng.annotations.BeforeClass; import org.testng.annotations.Test; -import hirs.tpm.eventlog.TCGEventLogTest; -import hirs.utils.HexUtils; -import hirs.tpm.eventlog.uefi.UefiGuid; -import hirs.tpm.eventlog.uefi.UefiPartition; +import java.io.IOException; +import java.net.URISyntaxException; +import java.nio.file.Paths; +import java.security.NoSuchAlgorithmException; +import java.security.cert.CertificateException; +import java.util.ArrayList; /** - * Class for testing TCG Event Log Event processing. + * Class for testing TCG Event Log Event processing. */ public class TCGEventLogEventsTest { - // Variable files collected using an Event Parsing tool + // Variable files collected using an Event Parsing tool private static final String EVENT_SPECID = "/tcgeventlog/events/EvEfiSpecId.txt"; private static final String EVENT_BOOTSERVICES - = "/tcgeventlog/events/EvBootServicesApplication.txt"; + = "/tcgeventlog/events/EvBootServicesApplication.txt"; private static final String EVENT_GPT_PARTITION - = "/tcgeventlog/events/EvEfiGptPartition.txt"; + = "/tcgeventlog/events/EvEfiGptPartition.txt"; private static final String EVENT_HANDOFF_TABLES = "/tcgeventlog/events/EvHandoffTables.txt"; private static final String UEFI_POST_CODE = "/tcgeventlog/events/EvPostCode.txt"; private static final Logger LOGGER - = LogManager.getLogger(TCGEventLogTest.class); + = LogManager.getLogger(TCGEventLogTest.class); + private static final String JSON_FILE = "/tcgeventlog/uefi/vendor-table.json"; /** * Initializes a SessionFactory. @@ -50,111 +52,120 @@ public class TCGEventLogEventsTest { LOGGER.debug("closing session factory"); } -/** - * Tests the processing of a SpecIDEvent event. - * @throws IOException when processing the test fails - */ -@Test -public final void testSpecIDEvent() throws IOException { - LOGGER.debug("Testing the SpecID Event Processing"); - String event = IOUtils.toString(this.getClass().getResourceAsStream(EVENT_SPECID), "UTF-8"); - byte[] eventBytes = HexUtils.hexStringToByteArray(event); - EvEfiSpecIdEvent specEvent = new EvEfiSpecIdEvent(eventBytes); - Assert.assertTrue(specEvent.isCryptoAgile()); - Assert.assertEquals(specEvent.getSignature(), "Spec ID Event03"); -} + /** + * Tests the processing of a SpecIDEvent event. + * + * @throws IOException when processing the test fails + */ + @Test + public final void testSpecIDEvent() throws IOException { + LOGGER.debug("Testing the SpecID Event Processing"); + String event = IOUtils.toString(this.getClass().getResourceAsStream(EVENT_SPECID), "UTF-8"); + byte[] eventBytes = HexUtils.hexStringToByteArray(event); + EvEfiSpecIdEvent specEvent = new EvEfiSpecIdEvent(eventBytes); + Assert.assertTrue(specEvent.isCryptoAgile()); + Assert.assertEquals(specEvent.getSignature(), "Spec ID Event03"); + } -/** - * Tests the processing of a Boot Services App event. - * @throws IOException when processing the test fails - * @throws NoSuchAlgorithmException if an unknown algorithm is encountered. - * @throws CertificateException if a certificate fails to parse. - */ -@Test -public final void testEvBootServicesApp() throws IOException { - LOGGER.debug("Testing the parsing of Boot Services Application Event"); - String event = IOUtils.toString(this.getClass().getResourceAsStream(EVENT_BOOTSERVICES), - "UTF-8"); - byte[] eventBytes = HexUtils.hexStringToByteArray(event); - EvEfiBootServicesApp bootService = new EvEfiBootServicesApp(eventBytes); - String address = HexUtils.byteArrayToHexString(bootService.getImagePhysicalAddress()); - Assert.assertEquals(address, "1820d45800000000"); - String path = bootService.getDevicePath().toString(); - Assert.assertTrue(path.contains("PIWG Firmware Volume b6ede22c-de30-45fa-bb09-ca202c1654b7")); -} + /** + * Tests the processing of a Boot Services App event. + * + * @throws IOException when processing the test fails + * @throws NoSuchAlgorithmException if an unknown algorithm is encountered. + * @throws CertificateException if a certificate fails to parse. + */ + @Test + public final void testEvBootServicesApp() throws IOException { + LOGGER.debug("Testing the parsing of Boot Services Application Event"); + String event = IOUtils.toString(this.getClass().getResourceAsStream(EVENT_BOOTSERVICES), + "UTF-8"); + byte[] eventBytes = HexUtils.hexStringToByteArray(event); + EvEfiBootServicesApp bootService = new EvEfiBootServicesApp(eventBytes); + String address = HexUtils.byteArrayToHexString(bootService.getImagePhysicalAddress()); + Assert.assertEquals(address, "1820d45800000000"); + String path = bootService.getDevicePath().toString(); + Assert.assertTrue(path.contains("PIWG Firmware Volume " + + "b6ede22c-de30-45fa-bb09-ca202c1654b7")); + } -/** - * Tests the processing of a Boot Services App event. - * @throws IOException when processing the test fails - * @throws NoSuchAlgorithmException if an unknown algorithm is encountered. - * @throws CertificateException if a certificate fails to parse. - */ -@Test -public final void testEvGptPartiton() throws IOException { - LOGGER.debug("Testing the parsing of Boot Services Application Event"); - String event = IOUtils.toString(this.getClass().getResourceAsStream(EVENT_GPT_PARTITION), - "UTF-8"); - byte[] eventBytes = HexUtils.hexStringToByteArray(event); - EvEfiGptPartition partition = new EvEfiGptPartition(eventBytes); - ArrayList partitonList = partition.getPartitionList(); - int partNumber = 1; - for (UefiPartition parition:partitonList) { - UefiGuid guidPart = parition.getPartitionTypeGUID(); - UefiGuid guidUnique = parition.getUniquePartitionGUID(); - String name = parition.getName(); - if (partNumber == 1) { - Assert.assertTrue(guidPart.toString(). - contains("de94bba4-06d1-4d40-a16a-bfd50179d6a")); - Assert.assertTrue(guidUnique.toString(). - contains("42cc8787-db23-4e45-9981-701adc801dc7")); - Assert.assertEquals(name, "Basic data partition"); - } - if (partNumber == 2) { - Assert.assertTrue(guidPart.toString(). - contains("c12a7328-f81f-11d2-ba4b-00a0c93ec93b")); - Assert.assertTrue(guidUnique.toString(). - contains("8ca7623c-041e-4fab-8c12-f49a86b85d73")); - Assert.assertEquals(name, "EFI system partition"); - } - if (partNumber++ == 3) { - Assert.assertTrue(guidPart.toString(). - contains("e3c9e316-0b5c-4db8-817d-f92df00215ae")); - Assert.assertTrue(guidUnique.toString(). - contains("d890cfff-320c-4f45-b6cf-a4d8bee6d9cb")); - Assert.assertEquals(name, "Microsoft reserved partition"); + /** + * Tests the processing of a Boot Services App event. + * + * @throws IOException when processing the test fails + * @throws NoSuchAlgorithmException if an unknown algorithm is encountered. + * @throws CertificateException if a certificate fails to parse. + */ + @Test + public final void testEvGptPartiton() throws IOException { + LOGGER.debug("Testing the parsing of Boot Services Application Event"); + String event = IOUtils.toString(this.getClass().getResourceAsStream(EVENT_GPT_PARTITION), + "UTF-8"); + byte[] eventBytes = HexUtils.hexStringToByteArray(event); + EvEfiGptPartition partition = new EvEfiGptPartition(eventBytes); + ArrayList partitonList = partition.getPartitionList(); + int partNumber = 1; + for (UefiPartition parition : partitonList) { + UefiGuid guidPart = parition.getPartitionTypeGUID(); + UefiGuid guidUnique = parition.getUniquePartitionGUID(); + String name = parition.getName(); + if (partNumber == 1) { + Assert.assertTrue(guidPart.toString(). + contains("de94bba4-06d1-4d40-a16a-bfd50179d6a")); + Assert.assertTrue(guidUnique.toString(). + contains("42cc8787-db23-4e45-9981-701adc801dc7")); + Assert.assertEquals(name, "Basic data partition"); + } + if (partNumber == 2) { + Assert.assertTrue(guidPart.toString(). + contains("c12a7328-f81f-11d2-ba4b-00a0c93ec93b")); + Assert.assertTrue(guidUnique.toString(). + contains("8ca7623c-041e-4fab-8c12-f49a86b85d73")); + Assert.assertEquals(name, "EFI system partition"); + } + if (partNumber++ == 3) { + Assert.assertTrue(guidPart.toString(). + contains("e3c9e316-0b5c-4db8-817d-f92df00215ae")); + Assert.assertTrue(guidUnique.toString(). + contains("d890cfff-320c-4f45-b6cf-a4d8bee6d9cb")); + Assert.assertEquals(name, "Microsoft reserved partition"); + } } } -} -/** - * Tests the processing of a Hand off Table event. - * @throws IOException when processing the test fails - */ -@Test -public final void testHandOffTables() throws IOException { - LOGGER.debug("Testing the Hand Off Tables Event Processing"); - String event = IOUtils.toString(this.getClass(). - getResourceAsStream(EVENT_HANDOFF_TABLES), "UTF-8"); - byte[] eventBytes = HexUtils.hexStringToByteArray(event); - EvEfiHandoffTable hTable = new EvEfiHandoffTable(eventBytes); - Assert.assertEquals(hTable.getNumberOfTables(), 1); - String tableInfo = hTable.toString(); - Assert.assertTrue(tableInfo.toString(). - contains("UEFI industry standard table type = SMBIOS3_TABLE_GUID")); -} + /** + * Tests the processing of a Hand off Table event. + * + * @throws IOException when processing the test fails + */ + @Test + public final void testHandOffTables() throws IOException, URISyntaxException { + LOGGER.debug("Testing the Hand Off Tables Event Processing"); + String event = IOUtils.toString(this.getClass(). + getResourceAsStream(EVENT_HANDOFF_TABLES), "UTF-8"); + byte[] eventBytes = HexUtils.hexStringToByteArray(event); + EvEfiHandoffTable hTable = new EvEfiHandoffTable(eventBytes, + Paths.get(this.getClass().getResource(JSON_FILE).toURI())); + Assert.assertEquals(hTable.getNumberOfTables(), 1); + String tableInfo = hTable.toString(); + LOGGER.error(tableInfo); + Assert.assertTrue(tableInfo. + contains("UEFI industry standard table type = SMBIOS3_TABLE_GUID")); + } -/** - * Tests the processing of a Post Code event. - * @throws IOException when processing the test fails - */ -@Test -public final void testPostCode() throws IOException { - LOGGER.debug("Testing the Post Code Event Processing"); - String event = IOUtils.toString(this.getClass().getResourceAsStream(UEFI_POST_CODE), "UTF-8"); - byte[] eventBytes = HexUtils.hexStringToByteArray(event); - EvPostCode pCode = new EvPostCode(eventBytes); - Assert.assertTrue(pCode.isString()); - String postCode = pCode.toString(); - Assert.assertEquals(postCode, "ACPI DATA"); - } + /** + * Tests the processing of a Post Code event. + * + * @throws IOException when processing the test fails + */ + @Test + public final void testPostCode() throws IOException { + LOGGER.debug("Testing the Post Code Event Processing"); + String event = IOUtils.toString(this.getClass().getResourceAsStream(UEFI_POST_CODE), + "UTF-8"); + byte[] eventBytes = HexUtils.hexStringToByteArray(event); + EvPostCode pCode = new EvPostCode(eventBytes); + Assert.assertTrue(pCode.isString()); + String postCode = pCode.toString(); + Assert.assertEquals(postCode, "ACPI DATA"); + } }