diff --git a/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/controllers/ReferenceManifestDetailsPageController.java b/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/controllers/ReferenceManifestDetailsPageController.java index 25f6245c..e2ed2b60 100644 --- a/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/controllers/ReferenceManifestDetailsPageController.java +++ b/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/controllers/ReferenceManifestDetailsPageController.java @@ -13,7 +13,8 @@ import java.nio.file.NoSuchFileException; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; - +import java.security.NoSuchAlgorithmException; +import java.security.cert.CertificateException; import java.util.Arrays; import java.util.HashMap; import java.util.List; @@ -106,9 +107,12 @@ public class ReferenceManifestDetailsPageController * @param referenceManifestManager the reference manifest manager. * @return mapping of the RIM information from the database. * @throws java.io.IOException error for reading file bytes. + * @throws NoSuchAlgorithmException If an unknown Algorithm is encountered. + * @throws CertificateException if a certificate doesn't parse. */ public static HashMap getRimDetailInfo(final UUID uuid, - final ReferenceManifestManager referenceManifestManager) throws IOException { + final ReferenceManifestManager referenceManifestManager) throws IOException, + CertificateException, NoSuchAlgorithmException { HashMap data = new HashMap<>(); ReferenceManifest rim = ReferenceManifest diff --git a/HIRS_Utils/src/main/java/hirs/tpm/eventlog/TCGEventLog.java b/HIRS_Utils/src/main/java/hirs/tpm/eventlog/TCGEventLog.java index 5726f2df..6929838c 100644 --- a/HIRS_Utils/src/main/java/hirs/tpm/eventlog/TCGEventLog.java +++ b/HIRS_Utils/src/main/java/hirs/tpm/eventlog/TCGEventLog.java @@ -1,94 +1,84 @@ package hirs.tpm.eventlog; -import hirs.utils.HexUtils; import java.io.ByteArrayInputStream; import java.io.IOException; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; +import java.security.cert.CertificateException; import java.util.ArrayList; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; +import hirs.tpm.eventlog.events.EvConstants; +import hirs.utils.HexUtils; /** * Class for handling different formats of TCG Event logs. */ -public class TCGEventLog { +public final class TCGEventLog { - private static final Logger LOGGER - = LogManager.getLogger(TCGEventLog.class); +// private static final Logger LOGGER = (Logger) LogManager.getLogger(TCGEventLog.class); - /** - * Init value for SHA 256 values. - */ + /** Initial value for SHA 256 values.*/ public static final String INIT_SHA256_LIST = "00000000000000000000000000" + "00000000000000000000000000000000000000"; - /** - * Init value for SHA 1 values. - */ + /** Initial value for SHA 1 values. */ public static final String INIT_SHA1_LIST = "0000000000000000000000000000000000000000"; - - /** - * PFP defined EV_NO_ACTION identifier. - */ + /** PFP defined EV_NO_ACTION identifier. */ public static final int NO_ACTION_EVENT = 0x00000003; - /** - * String value of SHA1 hash. - */ + /** String value of SHA1 hash.*/ public static final String HASH_STRING = "SHA1"; - /** - * String value of SHA256 hash. - */ + /** String value of SHA256 hash. */ public static final String HASH256_STRING = "SHA-256"; - /** - * Each PCR bank holds 24 registers. - */ + /** Each PCR bank holds 24 registers. */ public static final int PCR_COUNT = 24; - /** - * 2 dimensional array holding the PCR values. - */ - private final byte[][] pcrList; - /** - * List of parsed events within the log. - */ - private final ArrayList eventList = new ArrayList<>(); - + /** 2 dimensional array holding the PCR values. */ + private byte[][] pcrList; + /** List of parsed events within the log. */ + private ArrayList eventList = new ArrayList<>(); + /** Length of PCR. Indicates which hash algorithm is used. */ private int pcrLength; + /** Name of hash algorithm. */ private String hashType; + /** Initial Value to use. */ private String initValue; /** * Default blank object constructor. */ public TCGEventLog() { - this.pcrList = new byte[PCR_COUNT][TpmPcrEvent.SHA1_LENGTH]; + this.pcrList = new byte[PCR_COUNT][EvConstants.SHA1_LENGTH]; initValue = INIT_SHA1_LIST; - pcrLength = TpmPcrEvent.SHA1_LENGTH; + pcrLength = EvConstants.SHA1_LENGTH; initPcrList(); } /** * Default constructor for just the rawlog that'll set up SHA1 Log. - * @param rawlog data for the event log file - * @throws IOException IO Stream for the event log + * @param rawlog data for the event log file. + * @throws NoSuchAlgorithmException if an unknown algorithm is encountered. + * @throws CertificateException if a certificate in the log cannot be parsed. + * @throws IOException IO Stream if event cannot be parsed. */ - public TCGEventLog(final byte[] rawlog) throws IOException { - this(rawlog, TpmPcrEvent.SHA1_LENGTH, HASH_STRING, INIT_SHA1_LIST); + public TCGEventLog(final byte[] rawlog) throws CertificateException, NoSuchAlgorithmException, + IOException { + this(rawlog, EvConstants.SHA1_LENGTH, HASH_STRING, INIT_SHA1_LIST); } /** * Default constructor for specific log. * @param rawlog data for the event log file - * @param pcrLength determined by SHA1 or 256 - * @param hashType the type of algorithm - * @param initValue the default blank value + * @param pLength determined by SHA1 or 256 + * @param hType the type of algorithm + * @param iValue the default blank value. * @throws IOException IO Stream for the event log + * @throws NoSuchAlgorithmException if an unknown algorithm is encountered. + * @throws CertificateException f a certificate in the log cannot be parsed. */ - public TCGEventLog(final byte[] rawlog, final int pcrLength, - final String hashType, final String initValue) throws IOException { - this.pcrLength = pcrLength; + public TCGEventLog(final byte[] rawlog, final int pLength, final String hType, + final String iValue) throws IOException, CertificateException, + NoSuchAlgorithmException { + pcrLength = pLength; this.pcrList = new byte[PCR_COUNT][pcrLength]; - this.hashType = hashType; - this.initValue = initValue; + hashType = hType; + initValue = iValue; ByteArrayInputStream is = new ByteArrayInputStream(rawlog); // Process the 1st entry as a SHA1 format (per the spec) eventList.add(new TpmPcrEvent1(is)); @@ -132,7 +122,7 @@ public class TCGEventLog { 0, currentEvent.getDigestLength()); } } catch (NoSuchAlgorithmException e) { - LOGGER.error(e); + // ((org.apache.logging.log4j.Logger) LOGGER).error(e); } } } @@ -176,4 +166,5 @@ public class TCGEventLog { public String getExpectedPCRValue(final int index) { return HexUtils.byteArrayToHexString(pcrList[index]); } + } diff --git a/HIRS_Utils/src/main/java/hirs/tpm/eventlog/TCGEventLogProcessor.java b/HIRS_Utils/src/main/java/hirs/tpm/eventlog/TCGEventLogProcessor.java index 645b4bd0..878e2824 100644 --- a/HIRS_Utils/src/main/java/hirs/tpm/eventlog/TCGEventLogProcessor.java +++ b/HIRS_Utils/src/main/java/hirs/tpm/eventlog/TCGEventLogProcessor.java @@ -3,9 +3,13 @@ package hirs.tpm.eventlog; import java.io.IOException; import java.io.UnsupportedEncodingException; import java.math.BigInteger; +import java.security.NoSuchAlgorithmException; +import java.security.cert.CertificateException; import hirs.data.persist.TPMMeasurementRecord; import hirs.data.persist.TpmWhiteListBaseline; +import hirs.tpm.eventlog.events.EvConstants; +import hirs.tpm.eventlog.uefi.UefiConstants; import hirs.utils.HexUtils; import hirs.data.persist.Digest; import hirs.data.persist.DigestAlgorithm;; @@ -16,22 +20,16 @@ import hirs.data.persist.DigestAlgorithm;; * Constructor parses the input byte array into a List of TpmPcrEvents. */ public class TCGEventLogProcessor { - /** - * Name of the hash algorithm used to process the Event Log, default is SHA256. - */ + /** Name of the hash algorithm used to process the Event Log, default is SHA256. */ private String algorithm = "TPM_ALG_SHA256"; - /** - * Parsed event log array. - */ + /** Parsed event log array. */ private TCGEventLog tcgLog = null; - /** - * EV_NO_ACTION signature offset. - */ + /** EV_NO_ACTION signature offset. */ private static final int SIG_OFFSET = 32; - /** - * TEV_NO_ACTION signature size. - */ + /** TEV_NO_ACTION signature size. */ private static final int SIG_SIZE = 16; + /** Number of PCRs in a TPM PCR Bank. */ + private static final int PCR_COUNT = 24; /** * Default Constructor. @@ -43,12 +41,15 @@ public class TCGEventLogProcessor { /** * Constructor. * - * @param rawLog the byte array holding the contents of the TCG Event Log - * @throws IOException if there is a parsing error + * @param rawLog the byte array holding the contents of the TCG Event Log. + * @throws IOException IO Stream for the event log. + * @throws NoSuchAlgorithmException if an unknown algorithm is encountered. + * @throws CertificateException f a certificate in the log cannot be parsed. */ - public TCGEventLogProcessor(final byte[] rawLog) throws IOException { + public TCGEventLogProcessor(final byte[] rawLog) throws IOException, CertificateException, + NoSuchAlgorithmException { if (isLogCrytoAgile(rawLog)) { - tcgLog = new TCGEventLog(rawLog, TpmPcrEvent.SHA256_LENGTH, + tcgLog = new TCGEventLog(rawLog, EvConstants.SHA256_LENGTH, TCGEventLog.HASH256_STRING, TCGEventLog.INIT_SHA256_LIST); } else { tcgLog = new TCGEventLog(rawLog); @@ -104,7 +105,7 @@ public class TCGEventLogProcessor { TpmWhiteListBaseline baseline = new TpmWhiteListBaseline(name); TPMMeasurementRecord record; String pcrValue; - for (int i = 0; i < TpmPcrEvent.PCR_COUNT; i++) { + for (int i = 0; i < PCR_COUNT; i++) { if (algorithm.compareToIgnoreCase("TPM_ALG_SHA1") == 0) { // Log Was SHA1 Format pcrValue = tcgLog.getExpectedPCRValue(i); byte[] hexValue = HexUtils.hexStringToByteArray(pcrValue); @@ -127,11 +128,11 @@ public class TCGEventLogProcessor { * * @param log The Event Log * @return true if EfiSpecIDEvent is found and indicates that the format is crypto agile - * @throws UnsupportedEncodingException + * @throws UnsupportedEncodingException if parsing error occurs. */ - private boolean isLogCrytoAgile(final byte[] log) throws UnsupportedEncodingException { - byte[] eType = new byte[TpmPcrEvent.INT_LENGTH]; - System.arraycopy(log, TpmPcrEvent.INT_LENGTH, eType, 0, TpmPcrEvent.INT_LENGTH); + public boolean isLogCrytoAgile(final byte[] log) throws UnsupportedEncodingException { + byte[] eType = new byte[UefiConstants.SIZE_4]; + System.arraycopy(log, UefiConstants.SIZE_4, eType, 0, UefiConstants.SIZE_4); byte[] eventType = HexUtils.leReverseByte(eType); int eventID = new BigInteger(eventType).intValue(); if (eventID != TCGEventLog.NO_ACTION_EVENT) { diff --git a/HIRS_Utils/src/main/java/hirs/tpm/eventlog/TcgTpmtHa.java b/HIRS_Utils/src/main/java/hirs/tpm/eventlog/TcgTpmtHa.java index 68d109d3..08e562f5 100644 --- a/HIRS_Utils/src/main/java/hirs/tpm/eventlog/TcgTpmtHa.java +++ b/HIRS_Utils/src/main/java/hirs/tpm/eventlog/TcgTpmtHa.java @@ -15,63 +15,36 @@ import hirs.utils.HexUtils; * } TPMT_HA; */ public class TcgTpmtHa { - /** - * TCG Defined Algorithm Identifiers . - */ + /** TCG Defined Algorithm Identifiers. */ private int hashAlgId = 0; - /** - * Length of the hash. - */ + /** Length of the hash. */ private int hashLength = 0; - /** - * Human readable name of the hash algorithm. - */ + /** Human readable name of the hash algorithm. */ private String hashName = ""; - /** - * Hash data. - */ + /** Hash data. */ private byte[] digest = null; - /** - * TCG ID for SHA1. - */ + /** TCG ID for SHA1. */ public static final int TPM_ALG_SHA1 = 0x04; - /** - * TCG ID for SHA1. - */ + /** TCG ID for SHA1. */ public static final int TPM_ALG_SHA256 = 0x0B; - /** - * TCG ID for SHA 384. - */ + /** * TCG ID for SHA 384. */ public static final int TPM_ALG_SHA384 = 0x0C; - /** - * TCG ID for SHA512. - */ + /** TCG ID for SHA512. */ public static final int TPM_ALG_SHA_512 = 0x0D; - /** - * TCG ID for Null algorithm. - */ + /** TCG ID for Null algorithm. */ public static final int TPM_ALG_NULL = 0x10; - /** - * TCG ID for SHA1. - */ + /** TCG ID for SHA1. */ public static final int TPM_ALG_SHA1_LENGTH = 20; - /** - * TCG ID for SHA1. - */ + /** TCG ID for SHA1. */ public static final int TPM_ALG_SHA256_LENGTH = 32; - /** - * TCG ID for SHA 384. - */ + /** TCG ID for SHA 384. */ public static final int TPM_ALG_SHA384_LENGTH = 48; - /** - * TCG ID for SHA512. - */ + /** TCG ID for SHA512. */ public static final int TPM_ALG_SHA512_LENGTH = 64; - /** - * TCG ID for Null algorithm. - */ + /** TCG ID for Null algorithm. */ public static final int TPM_ALG_NULL_LENGTH = 0; - + /** buffer to hold the structure. */ + private byte[] buffer = null; /** * Constructor. * @@ -87,6 +60,9 @@ public class TcgTpmtHa { hashLength = tcgAlgLength(algID[0]); digest = new byte[hashLength]; is.read(digest); + buffer = new byte[algID.length + digest.length]; + System.arraycopy(algID, 0, buffer, 0, algID.length); + System.arraycopy(digest, 0, buffer, algID.length, digest.length); } /** @@ -98,6 +74,14 @@ public class TcgTpmtHa { return hashAlgId; } + /** + * Returns the contents of the TPMT_HA structure buffer. + * @return contents of the TPMT_HA structure. + */ + public byte[] getBuffer() { + return java.util.Arrays.copyOf(buffer, buffer.length); + } + /** * Return the length of the Hash. * diff --git a/HIRS_Utils/src/main/java/hirs/tpm/eventlog/TpmPcrEvent.java b/HIRS_Utils/src/main/java/hirs/tpm/eventlog/TpmPcrEvent.java index 40f7cd30..aeb559c6 100644 --- a/HIRS_Utils/src/main/java/hirs/tpm/eventlog/TpmPcrEvent.java +++ b/HIRS_Utils/src/main/java/hirs/tpm/eventlog/TpmPcrEvent.java @@ -3,7 +3,26 @@ package hirs.tpm.eventlog; import java.io.ByteArrayInputStream; import java.io.IOException; import java.math.BigInteger; +import java.nio.charset.StandardCharsets; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.security.cert.CertificateException; +import java.util.Arrays; +import hirs.tpm.eventlog.events.EvConstants; +import hirs.tpm.eventlog.events.EvCompactHash; +import hirs.tpm.eventlog.events.EvEfiBootServicesApp; +import hirs.tpm.eventlog.events.EvEfiGptPartition; +import hirs.tpm.eventlog.events.EvEfiHandoffTable; +import hirs.tpm.eventlog.events.EvEfiSpecIdEvent; +import hirs.tpm.eventlog.events.EvEventTag; +import hirs.tpm.eventlog.events.EvIPL; +import hirs.tpm.eventlog.events.EvNoAction; +import hirs.tpm.eventlog.events.EvPostCode; +import hirs.tpm.eventlog.events.EvSCrtmContents; +import hirs.tpm.eventlog.events.EvSCrtmVersion; +import hirs.tpm.eventlog.uefi.UefiFirmware; +import hirs.tpm.eventlog.uefi.UefiVariable; import hirs.utils.HexUtils; /** @@ -11,71 +30,49 @@ import hirs.utils.HexUtils; * TCG_PCR_EVENT is used when the Event log uses the SHA1 Format as described in the * TCG Platform Firmware Profile (PFP) specification. * typedef struct { - * TCG_PCRINDEX PCRIndex; //PCR Index value that either - * //matches the PCRIndex of a - * //previous extend operation or - * //indicates that this Event Log - * //entry is not associated with - * //an extend operation - * TCG_EVENTTYPE EventType; //See Log event types defined in toStrng() - * TCG_DIGEST digest; //The hash of the event data - * UINT32 EventSize; //Size of the event data - * UINT8 Event[EventSize]; //The event data + * TCG_PCRINDEX PCRIndex; //PCR Index value that either + * //matches the PCRIndex of a + * //previous extend operation or + * //indicates that this Event Log + * //entry is not associated with + * //an extend operation + * TCG_EVENTTYPE EventType; //See Log event types defined in toStrng() + * TCG_DIGEST digest; //The hash of the event data + * UINT32 EventSize; //Size of the event data + * UINT8 Event[EventSize]; //The event data * } TCG_PCR_EVENT; */ public class TpmPcrEvent { - /** - * Type length = 4 bytes. - */ - public static final int EV_TYPE_SIZE = 4; - /** - * Event Log spec version. - */ - public static final int MIN_SIZE = 32; - /** - * Event Type (byte array). - */ - public static final int INT_LENGTH = 4; - /** - * Event Type (byte array). - */ - public static final int SHA1_LENGTH = 20; - /** - * Event Type (byte array). - */ - public static final int SHA256_LENGTH = 32; - /** - * Each PCR bank holds 24 registers. - */ - public static final int PCR_COUNT = 24; - /** - * PCR index. - */ + /** Log format. SHA1=1, Crytpo agile=2. */ + private int logFormat = -1; + /** PCR index. */ private int pcrIndex = -1; - /** - * Event Type (long). - */ + /** Event Type (long). */ private long eventType = 0; - /** - * Event digest. - */ + /** Event digest. */ private byte[] digest = null; - /** - * Even data. - */ + /** Even content data. */ private byte[] eventContent; - /** - * TCG Event Log spec version. - */ - private static String version = "Unknown"; - /** - * TCG Event Log errata version. - */ - private static String errata = "Unknown"; - /** - * Length (in bytes) of a pcr. - */ + /** TCG Event Log spec version. */ + private String version = "Unknown"; + /** TCG Event Log errata version. */ + private String errata = "Unknown"; + /** Length (in bytes) of a pcr. */ private int digestLength = 0; + /** Event Number. */ + private int eventNumber = 1; + /** Index. */ + private int index = -1; + /** Event Contents flag. */ + private boolean bEvContent = false; + /** Event hash for SHA1 event logs. */ + private byte[] eventDataSha1hash; + /** Event hash for Crypto Agile events. */ + private byte[] eventDataSha256hash; + /** Signature extension mask.*/ + private static final long SIGN_MASK = 0x00000000FFFFFFFFL; + /** Mask used to remove upper values from a long. */ + private static final long INT_MASK = 0x000000007FFFFFFFL; /** * Constructor. @@ -128,14 +125,30 @@ public class TpmPcrEvent { return pcrIndex; } + /** Sets the Log Format for this TCG Event. + * 1 = SHA1 Format, 2 = Crypto Agile format. + * @param format indicates log format. + */ + protected void setLogFormat(final int format) { + logFormat = format; + } + + /** + * Gets the Log Format for this TCG Event. + * 1 = SHA1 Format, 2 = Crypto Agile format. + * @return number representing the format. + */ + public int getLogFormat() { + return logFormat; + } + /** * Sets the EventType. * * @param type byte array holding the PFP defined log event type */ protected void setEventType(final byte[] type) { - byte[] evType = HexUtils.leReverseByte(type); - eventType = new BigInteger(evType).longValue(); + eventType = new BigInteger(HexUtils.leReverseByte(type)).longValue(); } /** @@ -183,8 +196,8 @@ public class TpmPcrEvent { * * @return byte array holding the events content field */ - protected byte[] getEventContent() { - return eventContent; + public byte[] getEventContent() { + return java.util.Arrays.copyOf(eventContent, eventContent.length); } /** @@ -205,4 +218,262 @@ public class TpmPcrEvent { public int getDigestLength() { return digestLength; } + + /** + * Parses the event content and creates a human readable description of each event. + * @param event the byte array holding the event data. + * @param eventContent the byte array holding the event content. + * @return String description of the event. + * @throws CertificateException if the event contains an event that cannot be processed. + * @throws NoSuchAlgorithmException if an event contains an unsupported algorithm. + * @throws IOException if the event cannot be parsed. + */ + public String processEvent(final byte[] event, final byte[] eventContent) + throws CertificateException, NoSuchAlgorithmException, IOException { + String description = ""; + int eventID = (int) eventType; + description += "Event# " + eventNumber++ + ": "; + description += "Index PCR[" + this.index + "]\n"; + description += "Event Type: 0x" + this.eventType + " " + eventString(eventID); + description += "\n"; + if (logFormat == 1) { // Digest + description += "digest (SHA-1): " + HexUtils.byteArrayToHexString(this.digest) + "\n"; + } else { + description += "digest (SHA256): " + HexUtils.byteArrayToHexString(this.digest) + "\n"; + } + // Calculate both the SHA1 and SHA256 on the event since this will equal the digest + // field of about half the log messages. + MessageDigest md1 = MessageDigest.getInstance("SHA-1"); + md1.update(event); + eventDataSha1hash = md1.digest(); + MessageDigest md2 = MessageDigest.getInstance("SHA-256"); + md2.update(event); + eventDataSha256hash = md2.digest(); + + switch (eventID) { + case EvConstants.EV_PREBOOT_CERT: + description += " EV_PREBOOT_CERT" + "\n"; + break; + case EvConstants.EV_POST_CODE: + EvPostCode postCode = new EvPostCode(eventContent); + description += "Event Content:\n" + postCode.toString() + "\n"; + break; + case EvConstants.EV_UNUSED: + break; + case EvConstants.EV_NO_ACTION: + EvNoAction noAction = new EvNoAction(eventContent); + description += "Event Content:\n" + noAction.toString(); + if (noAction.isSpecIDEvent()) { + EvEfiSpecIdEvent specID = noAction.getEvEfiSpecIdEvent(); + version = specID.getVersionMajor() + "." + specID.getVersionMinor(); + errata = specID.getErrata(); + } + break; + case EvConstants.EV_SEPARATOR: + if (EvPostCode.isAscii(eventContent)) { + String seperatorEventData = new String(eventContent, StandardCharsets.UTF_8); + if (!this.isEmpty(eventContent)) { + description += "Seperator event content = " + seperatorEventData + "\n"; + } + } + description += eventHashCheck(); + break; + case EvConstants.EV_ACTION: + description += "Event Content:\n" + + new String(eventContent, StandardCharsets.UTF_8) + "\n"; + description += eventHashCheck(); + break; + case EvConstants.EV_EVENT_TAG: + EvEventTag eventTag = new EvEventTag(eventContent); + description += eventTag.toString() + "\n"; + description += eventHashCheck(); + break; + case EvConstants.EV_S_CRTM_CONTENTS: + EvSCrtmContents sCrtmContents = new EvSCrtmContents(eventContent); + description += "Event Content:\n " + sCrtmContents.toString() + "\n"; + break; + case EvConstants.EV_S_CRTM_VERSION: + EvSCrtmVersion sCrtmVersion = new EvSCrtmVersion(eventContent); + description += "Event Content:\n" + sCrtmVersion.toString() + "\n"; + description += eventHashCheck(); + break; + case EvConstants.EV_CPU_MICROCODE: + break; + case EvConstants.EV_PLATFORM_CONFIG_FLAGS: + description += eventHashCheck(); + break; + case EvConstants.EV_TABLE_OF_DEVICES: + break; + case EvConstants.EV_COMPACT_HASH: + EvCompactHash compactHash = new EvCompactHash(eventContent); + description += "Event Content:\n" + compactHash.toString() + "\n"; + description += eventHashCheck(); + break; + case EvConstants.EV_IPL: + EvIPL ipl = new EvIPL(eventContent); + description += "Event Content:\n" + ipl.toString() + "\n"; + break; + case EvConstants.EV_IPL_PARTITION_DATA: + break; + case EvConstants.EV_NONHOST_CODE: + break; + case EvConstants.EV_NONHOST_CONFIG: + break; + case EvConstants.EV_NONHOST_INFO: + break; + case EvConstants.EV_EV_OMIT_BOOT_DEVICES_EVENTS: + break; + case EvConstants.EV_EFI_EVENT_BASE: + break; + case EvConstants.EV_EFI_VARIABLE_DRIVER_CONFIG: + UefiVariable efiVar = new UefiVariable(eventContent); + description += "Event Content:\n" + efiVar.toString(); + description += eventHashCheck(); + break; + case EvConstants.EV_EFI_VARIABLE_BOOT: + description += "Event Content:\n" + new UefiVariable(eventContent).toString(); + description += eventHashCheck(); + break; + case EvConstants.EV_EFI_BOOT_SERVICES_APPLICATION: + EvEfiBootServicesApp bootServices = new EvEfiBootServicesApp(eventContent); + 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(eventContent); + description += "Event Content:\n" + bootDriver.toString(); + break; + case EvConstants.EV_EFI_RUNTIME_SERVICES_DRIVER: + break; + case EvConstants.EV_EFI_GPT_EVENT: + description += "Event Content:\n" + new EvEfiGptPartition(eventContent).toString(); + description += eventHashCheck(); + break; + case EvConstants.EV_EFI_ACTION: + description += new String(eventContent, StandardCharsets.UTF_8) + "\n"; + description += eventHashCheck(); + break; + case EvConstants.EV_EFI_PLATFORM_FIRMWARE_BLOB: + description += "Event Content:\n" + + new UefiFirmware(eventContent).toString() + "\n"; + break; + case EvConstants.EV_EFI_HANDOFF_TABLES: + EvEfiHandoffTable efiTable = new EvEfiHandoffTable(eventContent); + description += "Event Content:\n" + efiTable.toString(); + break; + case EvConstants.EV_EFI_HCRTM_EVENT: + break; + case EvConstants.EV_EFI_VARIABLE_AUTHORITY: + description += "Event Content:\n" + new UefiVariable(eventContent).toString(); + break; + default: description += " Unknown Event found" + "\n"; + } + + if (bEvContent) { + description += "Event content (Hex) (" + event.length + "): " + + HexUtils.byteArrayToHexString(eventContent) + "\n\n"; + } + return description; + } + + /** + * Converts the Event ID into a String As defined in the TCG PC Client FW Profile. + * Event IDs have values larger than an integer,so a Long is used hold the value. + * @param event the event id. + * @return TCG defined String that represents the event id + */ + private static String eventString(final long event) { + String evString = ""; + long tmpEvent = event; + Long longEvent = Long.valueOf(tmpEvent & SIGN_MASK); // Remove signed extension + Long intEvent = Long.valueOf(tmpEvent & INT_MASK); // truncate to an int value + // Check to see if value is larger than an int, if it is then truncate the value + if (longEvent.longValue() > (long) Integer.MAX_VALUE) { + switch (intEvent.intValue()) { + case EvConstants.EV_EFI_EVENT_BASE: evString = "EV_EFI_EVENT_BASE"; break; + case EvConstants.EV_EFI_VARIABLE_DRIVER_CONFIG: + evString = "EV_EFI_VARIABLE_DRIVER_CONFIG"; break; + case EvConstants.EV_EFI_VARIABLE_BOOT: + evString = "EV_EFI_VARIABLE_BOOT"; break; + case EvConstants.EV_EFI_BOOT_SERVICES_APPLICATION: + evString = "EV_EFI_BOOT_SERVICES_APPLICATION"; break; + case EvConstants.EV_EFI_BOOT_SERVICES_DRIVER: + evString = "EV_EFI_BOOT_SERVICES_DRIVER"; break; + case EvConstants.EV_EFI_RUNTIME_SERVICES_DRIVER: + evString = "EV_EFI_RUNTIME_SERVICES_DRIVER"; break; + case EvConstants.EV_EFI_GPT_EVENT: evString = "EV_EFI_GPT_EVENT"; break; + case EvConstants.EV_EFI_ACTION: evString = "EV_EFI_ACTION"; break; + case EvConstants.EV_EFI_PLATFORM_FIRMWARE_BLOB: + evString = "EV_EFI_PLATFORM_FIRMWARE_BLOB"; break; + case EvConstants.EV_EFI_HANDOFF_TABLES: evString = "EV_EFI_HANDOFF_TABLES"; break; + case EvConstants.EV_EFI_HCRTM_EVENT: evString = "EV_EFI_HCRTM_EVENT"; break; + case EvConstants.EV_EFI_VARIABLE_AUTHORITY: + evString = "EV_EFI_VARIABLE_AUTHORITY"; break; + default: evString = "Unknown Event ID " + event + " encountered"; + } + } else { + switch (intEvent.intValue()) { + case EvConstants.EV_PREBOOT_CERT: evString = "EV_PREBOOT_CERT"; break; + case EvConstants.EV_POST_CODE: evString = "EV_POST_CODE"; break; + case EvConstants.EV_UNUSED: evString = "EV_Unused"; break; + case EvConstants.EV_NO_ACTION: evString = "EV_NO_ACTION"; break; + case EvConstants.EV_SEPARATOR: evString = "EV_SEPARATOR"; break; + case EvConstants.EV_ACTION: evString = "EV_ACTION"; break; + case EvConstants.EV_EVENT_TAG: evString = "EV_EVENT_TAG"; break; + case EvConstants.EV_S_CRTM_CONTENTS: evString = "EV_S_CRTM_CONTENTS"; break; + case EvConstants.EV_S_CRTM_VERSION: evString = "EV_S_CRTM_VERSION"; break; + case EvConstants.EV_CPU_MICROCODE: evString = "EV_CPU_MICROCODE"; break; + case EvConstants.EV_PLATFORM_CONFIG_FLAGS: evString = "EV_PLATFORM_CONFIG_FLAGS "; + break; + case EvConstants.EV_TABLE_OF_DEVICES: evString = "EV_TABLE_OF_DEVICES"; break; + case EvConstants.EV_COMPACT_HASH: evString = "EV_COMPACT_HASH"; break; + case EvConstants.EV_IPL: evString = "EV_IPL"; break; + case EvConstants.EV_IPL_PARTITION_DATA: evString = "EV_IPL_PARTITION_DATA"; break; + case EvConstants.EV_NONHOST_CODE: evString = "EV_NONHOST_CODE"; break; + case EvConstants.EV_NONHOST_CONFIG: evString = "EV_NONHOST_CONFIG"; break; + case EvConstants.EV_NONHOST_INFO: evString = "EV_NONHOST_INFO"; break; + case EvConstants.EV_EV_OMIT_BOOT_DEVICES_EVENTS: + evString = "EV_EV_OMIT_BOOT_DEVICES_EVENTS"; break; + default: evString = "Unknown Event ID " + event + " encountered"; + } + } + return evString; + } + + /** + * Human readable output of a check of input against the current event hash. + * @return human readable string. + */ + private String eventHashCheck() { + String result = ""; + if (logFormat == 1) { + if (Arrays.equals(this.digest, eventDataSha1hash)) { result + += "Event digest matched hash of the event data " + "\n"; + } else { + result += "Event digest DID NOT match the hash of the event data :" + + HexUtils.byteArrayToHexString(getEventDigest()) + "\n"; + } + } else { + if (Arrays.equals(this.digest, eventDataSha256hash)) { + result += "Event digest matched hash of the event data " + "\n"; + } else { + result += "Event digest DID NOT match the hash of the event data :" + + HexUtils.byteArrayToHexString(getEventDigest()) + "\n"; + } + } + return result; + } + + /** + * Checks a byte array for all zeros. + * @param array holds data to check. + * @return true of all zeros are found. + */ + public boolean isEmpty(final byte[] array) { + for (int i = 0; i < array.length; i++) { + if (array[i] != 0) { + return false; + } + } + return true; + } } diff --git a/HIRS_Utils/src/main/java/hirs/tpm/eventlog/TpmPcrEvent1.java b/HIRS_Utils/src/main/java/hirs/tpm/eventlog/TpmPcrEvent1.java index 489e2ccc..6a97e348 100644 --- a/HIRS_Utils/src/main/java/hirs/tpm/eventlog/TpmPcrEvent1.java +++ b/HIRS_Utils/src/main/java/hirs/tpm/eventlog/TpmPcrEvent1.java @@ -1,9 +1,13 @@ package hirs.tpm.eventlog; +import hirs.tpm.eventlog.events.EvConstants; +import hirs.tpm.eventlog.uefi.UefiConstants; import hirs.utils.HexUtils; import java.io.ByteArrayInputStream; import java.io.IOException; +import java.security.NoSuchAlgorithmException; +import java.security.cert.CertificateException; /** * Class to process a TCG_PCR_EVENT. @@ -27,25 +31,52 @@ public class TpmPcrEvent1 extends TpmPcrEvent { /** * Constructor. * - * @param is ByteArrayInputStream holding the TCG Log event - * @throws IOException if an error occurs in parsing the event + * @param is ByteArrayInputStream holding the TCG Log event. + * @throws IOException if an error occurs in parsing the event. + * @throws NoSuchAlgorithmException if an undefined algorithm is encountered. + * @throws CertificateException If a certificate within an event can't be processed. */ - public TpmPcrEvent1(final ByteArrayInputStream is) throws IOException { + public TpmPcrEvent1(final ByteArrayInputStream is) throws IOException, CertificateException, + NoSuchAlgorithmException { super(is); - setDigestLength(SHA1_LENGTH); - byte[] unit32Data = new byte[INT_LENGTH]; - if (is.available() > MIN_SIZE) { - is.read(unit32Data); - setPcrIndex(unit32Data); - is.read(unit32Data); - setEventType(unit32Data); - byte[] eventDigest = new byte[SHA1_LENGTH]; + setDigestLength(EvConstants.SHA1_LENGTH); + setLogFormat(1); + /** Event data. */ + byte[] event = null; + byte[] rawIndex = new byte[UefiConstants.SIZE_4]; + byte[] rawType = new byte[UefiConstants.SIZE_4]; + byte[] rawEventSize = new byte[UefiConstants.SIZE_4]; + byte[] eventDigest = new byte[EvConstants.SHA1_LENGTH]; + byte[] eventContent = null; + int eventSize = 0; + + if (is.available() > UefiConstants.SIZE_32) { + is.read(rawIndex); + setPcrIndex(rawIndex); + is.read(rawType); + setEventType(rawType); is.read(eventDigest); setEventDigest(eventDigest); - is.read(unit32Data); - int eventSize = HexUtils.leReverseInt(unit32Data); - byte[] eventContent = new byte[eventSize]; + is.read(rawEventSize); + eventSize = HexUtils.leReverseInt(rawEventSize); + eventContent = new byte[eventSize]; is.read(eventContent); + setEventContent(eventContent); + // copy entire event into a byte array for processing + int eventLength = rawIndex.length + rawType.length + eventDigest.length + + rawEventSize.length; + int offset = 0; + event = new byte[eventLength]; + System.arraycopy(rawIndex, 0, event, offset, rawIndex.length); + offset += rawIndex.length; + System.arraycopy(rawType, 0, event, offset, rawType.length); + offset += rawType.length; + System.arraycopy(eventDigest, 0, event, offset, eventDigest.length); + offset += eventDigest.length; + System.arraycopy(rawEventSize, 0, event, offset, rawEventSize.length); + offset += rawEventSize.length; + //System.arraycopy(eventContent, 0, event, offset, eventContent.length); + this.processEvent(event, eventContent); } - } + } } diff --git a/HIRS_Utils/src/main/java/hirs/tpm/eventlog/TpmPcrEvent2.java b/HIRS_Utils/src/main/java/hirs/tpm/eventlog/TpmPcrEvent2.java index 809195cb..6e692b15 100644 --- a/HIRS_Utils/src/main/java/hirs/tpm/eventlog/TpmPcrEvent2.java +++ b/HIRS_Utils/src/main/java/hirs/tpm/eventlog/TpmPcrEvent2.java @@ -2,8 +2,12 @@ package hirs.tpm.eventlog; import java.io.ByteArrayInputStream; import java.io.IOException; +import java.security.NoSuchAlgorithmException; +import java.security.cert.CertificateException; import java.util.ArrayList; +import hirs.tpm.eventlog.events.EvConstants; +import hirs.tpm.eventlog.uefi.UefiConstants; import hirs.utils.HexUtils; /** @@ -64,21 +68,33 @@ public class TpmPcrEvent2 extends TpmPcrEvent { * * @param is ByteArrayInputStream holding the TCG Log event * @throws IOException if an error occurs in parsing the event + * @throws NoSuchAlgorithmException if an undefined algorithm is encountered. + * @throws CertificateException If a certificate within an event can't be processed. */ - public TpmPcrEvent2(final ByteArrayInputStream is) throws IOException { + public TpmPcrEvent2(final ByteArrayInputStream is) throws IOException, CertificateException, + NoSuchAlgorithmException { super(is); - setDigestLength(SHA256_LENGTH); + setDigestLength(EvConstants.SHA256_LENGTH); + setLogFormat(2); + /** Event data. */ + byte[] event; + byte[] rawIndex = new byte[UefiConstants.SIZE_4]; + byte[] algCountBytes = new byte[UefiConstants.SIZE_4]; + byte[] rawType = new byte[UefiConstants.SIZE_4]; + byte[] rawEventSize = new byte[UefiConstants.SIZE_4]; + byte[] eventDigest = new byte[EvConstants.SHA256_LENGTH]; + byte[] eventContent = null; + TcgTpmtHa hashAlg = null; + int eventSize = 0; //TCG_PCR_EVENT2 - byte[] rawInt = new byte[INT_LENGTH]; - if (is.available() > MIN_SIZE) { - is.read(rawInt); - setPcrIndex(rawInt); - is.read(rawInt); - setEventType(rawInt); + if (is.available() > UefiConstants.SIZE_32) { + is.read(rawIndex); + setPcrIndex(rawIndex); + is.read(rawType); + setEventType(rawType); // TPML_DIGEST_VALUES - is.read(rawInt); - algCount = HexUtils.leReverseInt(rawInt); - TcgTpmtHa hashAlg = null; + is.read(algCountBytes); + algCount = HexUtils.leReverseInt(algCountBytes); // Process TPMT_HA, for (int i = 0; i < algCount; i++) { hashAlg = new TcgTpmtHa(is); @@ -87,11 +103,36 @@ public class TpmPcrEvent2 extends TpmPcrEvent { setEventDigest(hashAlg.getDigest()); } } - is.read(rawInt); - int eventSize = HexUtils.leReverseInt(rawInt); - byte[] eventContent = new byte[eventSize]; + is.read(rawEventSize); + eventSize = HexUtils.leReverseInt(rawEventSize); + eventContent = new byte[eventSize]; is.read(eventContent); setEventContent(eventContent); + int eventLength = rawIndex.length + rawType.length + eventDigest.length + + rawEventSize.length; + int offset = 0; + for (TcgTpmtHa hash:hashlist) { + eventLength += hash.getBuffer().length; + } + event = new byte[eventLength]; + System.arraycopy(rawIndex, 0, event, offset, rawIndex.length); + offset += rawIndex.length; + System.arraycopy(rawType, 0, event, offset, rawType.length); + offset += rawType.length; + System.arraycopy(eventDigest, 0, event, offset, eventDigest.length); + offset += eventDigest.length; + System.arraycopy(rawEventSize, 0, event, offset, rawEventSize.length); + offset += rawEventSize.length; + //System.arraycopy(eventContent, 0, event, offset, eventContent.length); + this.processEvent(event, eventContent); } } + + /** + * Returns a list of digests within this event. + * @return a list of digests. + */ + public ArrayList getHashList() { + return hashlist; + } } diff --git a/HIRS_Utils/src/main/java/hirs/tpm/eventlog/events/EvCompactHash.java b/HIRS_Utils/src/main/java/hirs/tpm/eventlog/events/EvCompactHash.java new file mode 100644 index 00000000..1a2df0e2 --- /dev/null +++ b/HIRS_Utils/src/main/java/hirs/tpm/eventlog/events/EvCompactHash.java @@ -0,0 +1,53 @@ +package hirs.tpm.eventlog.events; + +import java.io.UnsupportedEncodingException; + +import hirs.tpm.eventlog.uefi.UefiConstants; +import hirs.utils.HexUtils; + +/** + * Class to process the EV_COMPACT_HASH event. + * The Old 2005 PFP description of EV_COMPACT_HASH which provides 4 byte ESI field (a pointer). + * The 2019 PFP description allow the vendor to create event data that is "specified by the caller" + * however the for PCR 6 there is a constraint that it contain + * "The Event Data field SHALL be a unique string". + */ +public class EvCompactHash { + + /** Holds the Compact Hash description. */ + private String eventInfo = ""; + + /** + * Constructor that takes in the event data (hex string) and passes to function below. + * @param event byte array of the Event Compact Hash. + * @throws UnsupportedEncodingException if compact hash has non utf-8 characters. + */ + public EvCompactHash(final byte[] event) throws UnsupportedEncodingException { + hashEvent(event); + } + + /** + * Takes the event data (hex string) converts to readable output. + * This may be somewhat limited due to the unpublished nature of vendor specific data. + * @param event data to process. + * @return a human readable description. + * @throws UnsupportedEncodingException if compact hash has non utf-8 characters. + */ + public String hashEvent(final byte[] event) throws UnsupportedEncodingException { + // determine if old format is used + if (event.length == UefiConstants.SIZE_4) { // older PFP defines as 4 byte ESI pointer. + eventInfo = " ESI = " + HexUtils.byteArrayToHexString(event); + } else { // otherwise assume the event content is a string + eventInfo = " " + new String(event, "UTF-8"); + } + return eventInfo; + } + + /** + * Readable description of the Event Content, however limiting that may be. + * @return Event description. + */ + public String toString() { + return eventInfo; + } +} diff --git a/HIRS_Utils/src/main/java/hirs/tpm/eventlog/events/EvConstants.java b/HIRS_Utils/src/main/java/hirs/tpm/eventlog/events/EvConstants.java new file mode 100644 index 00000000..f7a8a64e --- /dev/null +++ b/HIRS_Utils/src/main/java/hirs/tpm/eventlog/events/EvConstants.java @@ -0,0 +1,89 @@ +package hirs.tpm.eventlog.events; + +/** + * Class for defining constants referenced in the PC Client + * Platform Firmware Profile specification. + * + */ +public final class EvConstants { + /** + * EvConstants constructor. + */ + private EvConstants() { + } + /** Type length = 4 bytes. */ + public static final int EV_TYPE_SIZE = 4; + /** Event Log spec version.*/ + public static final int MIN_SIZE = 32; + /** Event Type (byte array). */ + public static final int INT_LENGTH = 4; + /** Event Type (byte array). */ + public static final int SHA1_LENGTH = 20; + /** Event Type (byte array). */ + public static final int SHA256_LENGTH = 32; + /** Each PCR bank holds 24 registers. */ + public static final int PCR_COUNT = 24; + // Event IDs + /** Pre boot cert Event ID. */ + public static final int EV_PREBOOT_CERT = 0x00000000; + /** POST Code Event ID. */ + public static final int EV_POST_CODE = 0x00000001; + /** Unused Event ID. */ + public static final int EV_UNUSED = 0x00000002; + /** NoAction Event ID. */ + public static final int EV_NO_ACTION = 0x00000003; + /** NoAction Event ID. */ + public static final int EV_SEPARATOR = 0x00000004; + /** Action Event ID. */ + public static final int EV_ACTION = 0x00000005; + /** Event ID. */ + public static final int EV_EVENT_TAG = 0x00000006; + /** SCRTM Contents Event ID. */ + public static final int EV_S_CRTM_CONTENTS = 0x00000007; + /** SCRTM Version Event ID. */ + public static final int EV_S_CRTM_VERSION = 0x00000008; + /** CPU Microcode Event ID. */ + public static final int EV_CPU_MICROCODE = 0x00000009; + /** Platform Config Flags Event ID. */ + public static final int EV_PLATFORM_CONFIG_FLAGS = 0x0000000A; + /** Table of Devices Event ID. */ + public static final int EV_TABLE_OF_DEVICES = 0x0000000B; + /** Compact Hash Event ID. */ + public static final int EV_COMPACT_HASH = 0x0000000C; + /** IPL Event ID. */ + public static final int EV_IPL = 0x0000000D; + /** Partition Data Event ID. */ + public static final int EV_IPL_PARTITION_DATA = 0x0000000E; + /** Non Host Event ID. */ + public static final int EV_NONHOST_CODE = 0x0000000F; + /** Non Host Config Event ID. */ + public static final int EV_NONHOST_CONFIG = 0x00000010; + /** Non Host Info Event ID. */ + public static final int EV_NONHOST_INFO = 0x00000011; + /** Omit Boot Device Event ID. */ + public static final int EV_EV_OMIT_BOOT_DEVICES_EVENTS = 0x00000012; + /** EFI Event ID. */ + public static final int EV_EFI_EVENT_BASE = 0x80000000; + /** EFI Variable Driver Event ID. */ + public static final int EV_EFI_VARIABLE_DRIVER_CONFIG = 0x80000001; + /** EFI Variable Boot Driver Event ID. */ + public static final int EV_EFI_VARIABLE_BOOT = 0x80000002; + /** EFI Boot Services Application Event ID. */ + public static final int EV_EFI_BOOT_SERVICES_APPLICATION = 0x80000003; + /** EFI Boot Services Application Event ID. */ + public static final int EV_EFI_BOOT_SERVICES_DRIVER = 0x80000004; + /** EFI Runtime Services Driver Event ID. */ + public static final int EV_EFI_RUNTIME_SERVICES_DRIVER = 0x80000005; + /** EFI GPT Event ID. */ + public static final int EV_EFI_GPT_EVENT = 0x80000006; + /** EFI GPT Event ID. */ + public static final int EV_EFI_ACTION = 0x80000007; + /** Platform Firmware Blob Event ID. */ + public static final int EV_EFI_PLATFORM_FIRMWARE_BLOB = 0x80000008; + /** EFI Handoff Tables Event ID. */ + public static final int EV_EFI_HANDOFF_TABLES = 0x80000009; + /** HRCTM Event ID. */ + public static final int EV_EFI_HCRTM_EVENT = 0x80000010; + /** EFI Variable Authority Event ID. */ + public static final int EV_EFI_VARIABLE_AUTHORITY = 0x800000E0; +} diff --git a/HIRS_Utils/src/main/java/hirs/tpm/eventlog/events/EvEfiBootServicesApp.java b/HIRS_Utils/src/main/java/hirs/tpm/eventlog/events/EvEfiBootServicesApp.java new file mode 100644 index 00000000..57d00e22 --- /dev/null +++ b/HIRS_Utils/src/main/java/hirs/tpm/eventlog/events/EvEfiBootServicesApp.java @@ -0,0 +1,133 @@ +package hirs.tpm.eventlog.events; + +import java.io.UnsupportedEncodingException; + +import hirs.tpm.eventlog.uefi.UefiConstants; +import hirs.tpm.eventlog.uefi.UefiDevicePath; +import hirs.utils.HexUtils; + +/** + * Class to process the PC Client Firmware profile defined EV_EFI_BOOT_SERVICES_APPLICATION event. + * The EV_EFI_BOOT_SERVICES_APPLICATION event data contains the UEFI_IMAGE_LOAD_EVENT structure: + * struct tdUEFI_IMAGE_LOAD_EVENT { + * UEFI_PHYSICAL_ADDRESS ImageLocationInMemory; // PE/COFF image same as UINT64 + * UINT64 ImageLengthInMemory; + * UINT64 ImageLinkTimeAddress; + * UINT64 LengthOfDevicePath; + * UEFI_DEVICE_PATH DevicePath[LengthOfDevicePath]; // See UEFI spec for the encodings. + * } UEFI_IMAGE_LOAD_EVENT; + * + * DEVICE_PATH_PROTOCOL from the UEFI spec Section 10.1 page 284 of v2.8 + * + * #define EFI_DEVICE_PATH_PROTOCOL_GUID \09576e91-6d3f-11d2-8e39-00a0c969723b + * typedef struct _EFI_DEVICE_PATH_PROTOCOL { + * UINT8 Type; + * UINT8 SubType; + * UINT8 Length[2]; + * } EFI_DEVICE_PATH_PROTOCOL; // ref page of the UEFI spec + * + * Where Type and Subtype are defined the UEFI spec section 10.3.1 + * Type 0x01 – Hardware Device Path + * Type 0x02 – ACPI Device Path + * Type 0x03 – Messaging Device Path + * Type 0x04 – Media Device Path + * Type 0x05 – BIOS Boot Specification Device Path + * Type 0x7F – End of Hardware Device Path + */ +public class EvEfiBootServicesApp { + /** UEFI Address. */ + private byte[] physicalAddress = null; + /** UEFI Image Length. */ + private int imageLength = 0; + /** UEFI Link Time image address. */ + private byte[] linkTimeAddress = null; + /** UEFI Device Path Length. */ + private int devicePathLength = 0; + /** UEFI Device path. */ + private UefiDevicePath devPath = null; + /** Is the Device Path Valid. */ + private boolean devicePathValid = false; + + /** + * EvEFIBootServicesApp constructor. + * @param bootServices byte array holding the event data. + * @throws UnsupportedEncodingException if parsing issues exists. + */ + public EvEfiBootServicesApp(final byte[] bootServices) throws UnsupportedEncodingException { + physicalAddress = new byte[UefiConstants.SIZE_8]; + System.arraycopy(bootServices, 0, physicalAddress, 0, UefiConstants.SIZE_8); + byte[] lengthBytes = new byte[UefiConstants.SIZE_8]; + System.arraycopy(bootServices, UefiConstants.OFFSET_8, lengthBytes, 0, UefiConstants.SIZE_8); + imageLength = HexUtils.leReverseInt(lengthBytes); + linkTimeAddress = new byte[UefiConstants.SIZE_8]; + System.arraycopy(bootServices, UefiConstants.OFFSET_16, linkTimeAddress, 0, + UefiConstants.SIZE_8); + System.arraycopy(bootServices, UefiConstants.SIZE_24, lengthBytes, 0, UefiConstants.SIZE_8); + if (imageLength != 0) { + devicePathLength = HexUtils.leReverseInt(lengthBytes); + byte[] devPathBytes = new byte[devicePathLength]; + System.arraycopy(bootServices, UefiConstants.SIZE_32, devPathBytes, + 0, devicePathLength); + devPath = new UefiDevicePath(devPathBytes); + devicePathValid = true; + } + } + + /** + * Returns the address of the physical image of the boot services application. + * @return address of the physical image. + */ + public byte[] getImagePhysicalAddress() { + return java.util.Arrays.copyOf(physicalAddress, physicalAddress.length); + } + + /** + * Returns the length of a link time image referenced by this event. + * @return length of the link time image. + */ + public byte[] getImageLinkTimeAddress() { + return java.util.Arrays.copyOf(linkTimeAddress, linkTimeAddress.length); + } + + /** + * Returns the length of an image referenced by this event. + * @return length of the image. + */ + public int getImageLength() { + return imageLength; + } + + /** + * Returns the length of the device path. + * @return device path length. + */ + public int getDevicePathLength() { + return devicePathLength; + } + + /** + * Provide a uefi device path object contained in the event. + * @return UefiDevicePath object. + */ + public UefiDevicePath getDevicePath() { + return devPath; + } + +/** + * Returns a human readable string of the Boot Service info. + * @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 + "\n"; + if (devicePathValid) { + info += devPath.toString(); + } else { + info += " Error processing device path" + "\n"; + } + return info; + } +} diff --git a/HIRS_Utils/src/main/java/hirs/tpm/eventlog/events/EvEfiGptPartition.java b/HIRS_Utils/src/main/java/hirs/tpm/eventlog/events/EvEfiGptPartition.java new file mode 100644 index 00000000..c6b90622 --- /dev/null +++ b/HIRS_Utils/src/main/java/hirs/tpm/eventlog/events/EvEfiGptPartition.java @@ -0,0 +1,138 @@ +package hirs.tpm.eventlog.events; + +import java.io.UnsupportedEncodingException; +import java.math.BigInteger; +import java.util.ArrayList; + +import hirs.tpm.eventlog.uefi.UefiConstants; +import hirs.tpm.eventlog.uefi.UefiPartition; +import hirs.utils.HexUtils; + +/** + * Class to process the PC Client Firmware profile defined EV_EFI_GPT_EVENT event. + * The EV_EFI_GPT_EVENT event data contains the UEFI_GPT_DATA structure as defined in the PFP + * line 2860: + * + * typedef struct { + * UEFI_PARTITION_TABLE_HEADER UEFIPartitionHeader; // same as UINT64 for current x86 devices + * UINT64 NumberOfPartitions; + * UEFI_PARTITION_ENTRY Partitions [NumberOfPartitions]; + * }UEFI_GPT_DATA; + * + * The UEFI spec defines the EFI_TABLE_HEADER and EFI_PARTITION_ENTRY + * + * * typedef struct { + * UINT64 Signature; // A 64-bit signature that identifies the type of table that follows. + * UINT32 Revision; + * UINT32 HeaderSize; + * UINT32 CRC32; + * UINT32 Reserved; + * } EFI_TABLE_HEADER; + * + * typedef struct { + * EFI_GUID PartitionTypeGUID; + * EFI_GUID UniquePartitionGUID; + * EFI_LBA StartingLBA; // Same as UINT64. + * EFI_LBA EndingLBA; + * UINT64 Attributes; + * CHAR16 PartitionName[36]; // 36 CHAR16 = 72 Bytes + * } EFI_PARTITION_ENTRY; + * + * EFI_SYSTEM_TABLE_SIGNATURE 0x5453595320494249 + * EFI_BOOT_SERVICES_SIGNATURE 0x56524553544f4f42 + * EFI_RUNTIME_SERVICES_SIGNATURE 0x56524553544e5552 + * + * UEFI Table 23. Defined GPT Partition Entry - Partition Type GUIDs + * Unused Entry 00000000-0000-0000-0000-000000000000 + * EFI System Partition C12A7328-F81F-11D2-BA4B-00A0C93EC93B + * Partition containing a legacy MBR 024DEE41-33E7-11D3-9D69-0008C781F39F + * + */ +public class EvEfiGptPartition { + /** Header Size. */ + private int headerSize = 0; + /** Header bytes. */ + private byte[] header = new byte[UefiConstants.SIZE_8]; + /** Number of partitions in this event. */ + private int numberOfPartitions; + /** Partition Length. */ + private int partitonEntryLength = UefiConstants.SIZE_128; + /** List of Partitions. */ + private ArrayList partitionList = new ArrayList(); + + /** + * GPT Partition Event Type constructor. + * @param eventDataBytes GPT Event to process + * @throws UnsupportedEncodingException if Event Data fails to parse + */ + public EvEfiGptPartition(final byte[] eventDataBytes) throws UnsupportedEncodingException { + //byte[] eventDataBytes = event.getEventContent(); + // Process the partition header + System.arraycopy(eventDataBytes, 0, header, 0, UefiConstants.SIZE_8); // Signature + byte[] revision = new byte[UefiConstants.SIZE_4]; + System.arraycopy(eventDataBytes, UefiConstants.SIZE_8, revision, 0, UefiConstants.SIZE_4); + byte[] hsize = new byte[UefiConstants.SIZE_4]; + System.arraycopy(eventDataBytes, UefiConstants.SIZE_12, hsize, 0, UefiConstants.SIZE_4); + headerSize = getIntFromBytes(hsize); + byte[] partitions = new byte[UefiConstants.SIZE_8]; + System.arraycopy(eventDataBytes, headerSize, partitions, 0, UefiConstants.SIZE_8); + numberOfPartitions = getIntFromBytes(partitions); + int partitionLength = numberOfPartitions * partitonEntryLength; + byte[] partitionEntries = new byte[partitionLength]; + System.arraycopy(eventDataBytes, headerSize + UefiConstants.SIZE_8, partitionEntries, + 0, partitionLength); + processesPartitions(partitionEntries, numberOfPartitions); + // Mystery Structure get processed here (skipped for now), still part of the header + } + + /** + * Returns a list of partitions described in the Event Log. + * @return UefiPartition List. + */ + public ArrayList getPartitionList() { + return partitionList; + } + + /** + * Processes an individual GPT partition entry. + * @param partitons byte array holding partition data. + * @param numberOfParititions number of partitions included in the data. + * @throws UnsupportedEncodingException if partition data fails to parse. + */ + private void processesPartitions(final byte[] partitons, final int numberOfParititions) + throws UnsupportedEncodingException { + byte[] partitionData = new byte[UefiConstants.SIZE_128]; + for (int i = 0; i < numberOfParititions; i++) { + System.arraycopy(partitons, i * partitonEntryLength, partitionData, 0, + partitonEntryLength); + partitionList.add(new UefiPartition(partitionData)); + } + } + + /** + * Provides a human readable string describing the GPT Partition information. + * @return a human readable string holding the partition information. + */ + public String toString() { + String headerStr = HexUtils.byteArrayToHexString(header); + StringBuilder partitionInfo = new StringBuilder(); + partitionInfo.append("GPT Header Signature = " + headerStr + " : Number of Paritions = " + + numberOfPartitions + "\n"); + for (int i = 0; i < numberOfPartitions; i++) { + partitionInfo.append("Partition " + i + " information\n"); + partitionInfo.append(partitionList.get(i).toString()); + } + return partitionInfo.toString(); + } + + /** + * Helper method for converting little Endian byte arrays into Big Endian integers. + * @param data data to convert. + * @return an integer. + */ + public int getIntFromBytes(final byte[] data) { + byte[] bigEndData = HexUtils.leReverseByte(data); + BigInteger bigInt = new BigInteger(bigEndData); + return bigInt.intValue(); + } +} 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 new file mode 100644 index 00000000..a50096db --- /dev/null +++ b/HIRS_Utils/src/main/java/hirs/tpm/eventlog/events/EvEfiHandoffTable.java @@ -0,0 +1,108 @@ + package hirs.tpm.eventlog.events; + +import java.util.ArrayList; + +import hirs.tpm.eventlog.uefi.UefiConstants; +import hirs.tpm.eventlog.uefi.UefiGuid; +import hirs.utils.HexUtils; + +import java.math.BigInteger; + +/** 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; + * + * The UEFI_CONFIGURATION_TABLE id defined in the UEFI spec as: + * + * 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. + */ +public class EvEfiHandoffTable { + /** Number of Tables. */ + private int tableCount = 0; + /** List of Vendor GUIDs. */ + private ArrayList vendorGuids = new ArrayList(); + /** List of Vendors. */ + private ArrayList vendorTables = new ArrayList(); + + /** + * EvEFIHandoffTable constructor. + * @param tpmEventData byte array holding the Handoff table data. + */ + public EvEfiHandoffTable(final byte[] tpmEventData) { + // 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(); + // 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; + } + + /** + * Returns the next GUI in the table. + * @param eventData byte array holding the guids. + * @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); + } + + /** + * 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. + * @return a byte array holding the new table. + */ + 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)) + "\n"); + } + return tableInfo.toString(); + } +} diff --git a/HIRS_Utils/src/main/java/hirs/tpm/eventlog/events/EvEfiSpecIdEvent.java b/HIRS_Utils/src/main/java/hirs/tpm/eventlog/events/EvEfiSpecIdEvent.java new file mode 100644 index 00000000..ac5f5f3e --- /dev/null +++ b/HIRS_Utils/src/main/java/hirs/tpm/eventlog/events/EvEfiSpecIdEvent.java @@ -0,0 +1,179 @@ +package hirs.tpm.eventlog.events; + +import java.io.UnsupportedEncodingException; +import java.util.ArrayList; + +import hirs.tpm.eventlog.TcgTpmtHa; +import hirs.tpm.eventlog.uefi.UefiConstants; +import hirs.utils.HexUtils; + +/** + * Class to process the TCG_EfiSpecIDEvent. + * The first 16 bytes of a Event Data MUST be 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 the format of the Log (SHA1 vs Crypt Agile). + * + * typedef struct tdTCG_EfiSpecIdEvent { + * BYTE Signature[16]; + * UINT32 platformClass; + * UINT8 specVersionMinor; + * UINT8 specVersionMajor; + * UINT8 specErrata; + * UINT8 uintnSize; + * UINT32 numberOfAlgorithms; + * TCG_EfiSpecIdEventAlgorithmSize digestSizes[numberOfAlgorithms]; + * UINT8 vendorInfoSize; + * BYTE vendorInfo[VendorInfoSize]; + * } TCG_EfiSpecIDEvent; + * + * typedef struct tdTCG_EfiSpecIdEventAlgorithmSize { + * UINT16 algorithmId; + * UINT16 digestSize; + * } TCG_EfiSpecIdEventAlgorithmSize; + * + * define TPM_ALG_SHA1 (TPM_ALG_ID)(0x0004) + * define TPM_ALG_SHA256 (TPM_ALG_ID)(0x000B) + * define TPM_ALG_SHA384 (TPM_ALG_ID)(0x000C) + * define TPM_ALG_SHA512 (TPM_ALG_ID)(0x000D) + * + * Notes: Parses event data for an EfiSpecID per Table 5 TCG_EfiSpecIdEvent Example. + * 1. Should be the first Structure in the log + * 2. Has an EventType of EV_NO_ACTION (0x00000003) + * 3. Digest of 20 bytes of all 0's + * 4. Event content defined as TCG_EfiSpecIDEvent Struct. + * 5. First 16 bytes of the structure is an ASCII "Spec ID Event03" + * 6. The version of the log is used to determine which format the Log + * is to use (sha1 or Crypto Agile) + */ +public class EvEfiSpecIdEvent { + /** Minor Version. */ + private String vMin = ""; + /** Major Version. */ + private String vMaj = ""; + /** Specification errata version. */ + private String errata = ""; + /** Signature (text) data. */ + private String signature = ""; + /** Platform class. */ + private String platformClass = ""; + /** Algorithm count. */ + private int numberOfAlg = 0; + /** True if event log uses Crypto Agile format. */ + private boolean cryptoAgile = false; + /** Algorithm list. */ + private ArrayList algList = new ArrayList(); + + /** + * EvEfiSpecIdEvent Constructor. + * @param efiSpecId byte array holding the spec ID Event. + * @throws UnsupportedEncodingException if input fails to parse. + */ + public EvEfiSpecIdEvent(final byte[] efiSpecId) throws UnsupportedEncodingException { + byte[] signatureBytes = new byte[UefiConstants.SIZE_16]; + System.arraycopy(efiSpecId, 0, signatureBytes, 0, UefiConstants.SIZE_16); + signature = HexUtils.byteArrayToHexString(signatureBytes); + signature = new String(signatureBytes, "UTF-8").substring(0, UefiConstants.SIZE_15); + + byte[] platformClassBytes = new byte[UefiConstants.SIZE_4]; + System.arraycopy(efiSpecId, UefiConstants.OFFSET_16, platformClassBytes, 0, + UefiConstants.SIZE_4); + platformClass = HexUtils.byteArrayToHexString(platformClassBytes); + + byte[] specVersionMinorBytes = new byte[1]; + System.arraycopy(efiSpecId, UefiConstants.OFFSET_20, specVersionMinorBytes, 0, 1); + vMin = HexUtils.byteArrayToHexString(specVersionMinorBytes); + + byte[] specVersionMajorBytes = new byte[1]; + System.arraycopy(efiSpecId, UefiConstants.OFFSET_21, specVersionMajorBytes, 0, 1); + vMaj = HexUtils.byteArrayToHexString(specVersionMajorBytes); + + byte[] specErrataBytes = new byte[1]; + System.arraycopy(efiSpecId, UefiConstants.OFFSET_22, specErrataBytes, 0, 1); + errata = HexUtils.byteArrayToHexString(specErrataBytes); + + byte[] numberOfAlgBytes = new byte[UefiConstants.SIZE_4]; + System.arraycopy(efiSpecId, UefiConstants.OFFSET_24, numberOfAlgBytes, 0, + UefiConstants.SIZE_4); + numberOfAlg = HexUtils.leReverseInt(numberOfAlgBytes); + + byte[] algorithmIDBytes = new byte[UefiConstants.SIZE_2]; + int algLocation = UefiConstants.SIZE_28; + for (int i = 0; i < numberOfAlg; i++) { + System.arraycopy(efiSpecId, algLocation + UefiConstants.OFFSET_4 * i, algorithmIDBytes, + 0, UefiConstants.SIZE_2); + 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; + } + } + + /** + * Returns the specification major revision. + * @return major revision. + */ + public String getVersionMajor() { + return vMaj; + } + /** + * Returns the specification minor revision. + * @return minor revision. + */ + public String getVersionMinor() { + return vMin; + } + /** + * Returns the specification eratta version. + * @return major revision. + */ + public String getErrata() { + return errata; + } + /** + * Returns the contents of the events signature field. + * @return signature data. + */ + public String getSignature() { + return signature; + } + /** + * Returns the class of the platform. + * @return platform class. + */ + public String getPlatformClass() { + return platformClass; + } + /** + * Returns a list of hash algorithms used in the event log. + * @return ArrayList of TCG defined algorithm identifiers. + */ + public ArrayList getAlgList() { + return algList; + } + /** + * Used to determine if the log uses the Crypto Agile format. + * @return boolean true if the algorithm is Crpyto Agile. + */ + public boolean isCryptoAgile() { + return cryptoAgile; + } + /** + * Returns a human readable description of the data within this event. + * @return a description of this event.. + */ + public String toString() { + String specInfo = ""; + if (signature == "Spec ID Event#") { + specInfo += "Platform Profile Specification version = " + vMaj + "." + vMin + + " using errata version" + errata + "\n"; + } else { + specInfo = "EV_NO_ACTION event named " + signature + + " ecncountered but support for processing it has not been added to this application"; + } + return specInfo; + } +} diff --git a/HIRS_Utils/src/main/java/hirs/tpm/eventlog/events/EvEventTag.java b/HIRS_Utils/src/main/java/hirs/tpm/eventlog/events/EvEventTag.java new file mode 100644 index 00000000..aa07d3a4 --- /dev/null +++ b/HIRS_Utils/src/main/java/hirs/tpm/eventlog/events/EvEventTag.java @@ -0,0 +1,69 @@ +package hirs.tpm.eventlog.events; + +import hirs.tpm.eventlog.uefi.UefiConstants; +import hirs.utils.HexUtils; + +/** + * Class for processing the EV_EVENT_TAG. + * The structure for the Event Data is defined as: + * structure tdTCG_PCClientTaggedEvent{ + * UINT32 taggedEventID; + * UINT32 taggedEventDataSize; + * BYTE taggedEventData[taggedEventDataSize]; + * } TCG_PCClientTaggedEvent; + * ToDo: Find lookup of taggedEventID and figure out how to process. + */ +public class EvEventTag { + /** Event Tag Information. */ + private String eventTagInfo = ""; + /** Event Tag ID. */ + private int tagEventID = 0; + /** Event ID. */ + private int eventID = 0; + /** Data size. */ + private int dataSize = 0; + + /** + * Processes event tag. + * @param eventTag byte array holding the eventTag data. + */ + public EvEventTag(final byte[] eventTag) { + if (eventTag.length < UefiConstants.SIZE_8) { + eventTagInfo = "Invalid EV Event Tag data"; + } else { + byte[] tagEventIdBytes = new byte[UefiConstants.SIZE_4]; + System.arraycopy(eventTag, 0, tagEventIdBytes, 0, UefiConstants.SIZE_4); + eventID = HexUtils.leReverseInt(tagEventIdBytes); + byte[] tagEventDataSize = new byte[UefiConstants.SIZE_4]; + System.arraycopy(eventTag, UefiConstants.OFFSET_4, tagEventDataSize, 0, + UefiConstants.SIZE_4); + dataSize = HexUtils.leReverseInt(tagEventDataSize); + } + } + /** + * Returns the event ID & data size. + * @return eventID + */ + public int getTagEventID() { + return tagEventID; + } + /** + * Returns the size of the UEFI variable. + * @return size of the UEFI variable. + */ + public int getDataSize() { + return dataSize; + } + + /** + * Returns a human readable string of the Event Tag. + * @return human readable string. + */ + public String toString() { + if (eventTagInfo.isEmpty()) { + eventTagInfo = " Tagged Event ID = " + eventID; + eventTagInfo += " Data Size = " + dataSize; + } + return eventTagInfo; + } +} diff --git a/HIRS_Utils/src/main/java/hirs/tpm/eventlog/events/EvIPL.java b/HIRS_Utils/src/main/java/hirs/tpm/eventlog/events/EvIPL.java new file mode 100644 index 00000000..d0e50cef --- /dev/null +++ b/HIRS_Utils/src/main/java/hirs/tpm/eventlog/events/EvIPL.java @@ -0,0 +1,43 @@ +package hirs.tpm.eventlog.events; + +import java.nio.charset.StandardCharsets; + +/** + * Processes event type EV_IPL which is deprecated in the current spec, + * but defined in older version of the specification(1.0.0) as contain + * "informative information about the IPL code" (ascii strings). + */ +public class EvIPL { + + private String description = ""; + + /** + *IPL Event Constructor. + * @param event byte array holding the IPL Event data. + */ + public EvIPL(final byte[] event) { + event(event); + } + + /** + * Processes IPL event. + * @param event byte array holding the IPL Event data. + * @return a description of the IPl event. + */ + public String event(final byte[] event) { + if (event == null) { + description = "Invalid IPL event data"; + } else { + description = " \"" + new String(event, StandardCharsets.UTF_8) + "\""; + } + return description; + } + + /** + * Returns a human readable description of the IPL Event. + * @return human readable description. + */ + public String toString() { + return description; + } +} diff --git a/HIRS_Utils/src/main/java/hirs/tpm/eventlog/events/EvNoAction.java b/HIRS_Utils/src/main/java/hirs/tpm/eventlog/events/EvNoAction.java new file mode 100644 index 00000000..252594ac --- /dev/null +++ b/HIRS_Utils/src/main/java/hirs/tpm/eventlog/events/EvNoAction.java @@ -0,0 +1,82 @@ +package hirs.tpm.eventlog.events; + +import java.io.UnsupportedEncodingException; +import java.nio.charset.StandardCharsets; + +import hirs.tpm.eventlog.uefi.UefiConstants; + +/** + * Class to process the EV_NO_ACTION event using a structure of TCG_EfiSpecIDEvent. + * 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). + * + * Notes: + * 1. First 16 bytes of the structure is an ASCII with a fixed Length of 16 + * 2. Add processing of other NoEvent types when new ones get defined + */ +public class EvNoAction { + + /** Signature (text) data. */ + private String signature = ""; + /** True of the event is a SpecIDEvent. */ + private boolean bSpecIDEvent = false; + /** EvEfiSpecIdEvent Object. */ + private EvEfiSpecIdEvent specIDEvent = null; + + /** + * EvNoAction constructor. + * @param eventData byte array holding the event to process. + * @throws UnsupportedEncodingException if input fails to parse. + */ + public EvNoAction(final byte[] eventData) throws UnsupportedEncodingException { + byte[] signatureBytes = new byte[UefiConstants.SIZE_15]; + System.arraycopy(eventData, 0, signatureBytes, 0, UefiConstants.SIZE_15); + 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); + bSpecIDEvent = true; + } + } + + /** + * Returns the EfiSpecIDEvent object (currently only NoAction event defined) + * or null if its not. + * @return EfiSpecIDEvent object or null. + */ + public EvEfiSpecIdEvent getEvEfiSpecIdEvent() { + return specIDEvent; + } + /** + * Determines if this event is a SpecIDEvent. + * @return true of the event is a SpecIDEvent. + */ + public boolean isSpecIDEvent() { + return bSpecIDEvent; + } + /** + * Returns a 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() + "\n"; + } + } else { + specInfo = "EV_NO_ACTION event named " + signature + + " encountered but support for processing it has not been added to this application.\n"; + } + return specInfo; + } +} diff --git a/HIRS_Utils/src/main/java/hirs/tpm/eventlog/events/EvPostCode.java b/HIRS_Utils/src/main/java/hirs/tpm/eventlog/events/EvPostCode.java new file mode 100644 index 00000000..5e52d9d9 --- /dev/null +++ b/HIRS_Utils/src/main/java/hirs/tpm/eventlog/events/EvPostCode.java @@ -0,0 +1,86 @@ +package hirs.tpm.eventlog.events; + +import java.nio.charset.StandardCharsets; + +import hirs.tpm.eventlog.uefi.UefiFirmware; + +/** + * Class for processing EV_POST_CODE event types + * + * typedef struct tdUEFI_PLATFORM_FIRMWARE_BLOB { + * UEFI_PHYSICAL_ADDRESS BlobBase; // Same as UINT64 for most systems + * UINT64 BlobLength; + * } UEFI_PLATFORM_FIRMWARE_BLOB; + * + * However Table 9 of the PC Client Platform firmware profile states that even content is a string + * For POST code, the event data SHOULD be “POST CODE”. + * For embedded SMM code, the event data SHOULD be “SMM CODE”. + * For ACPI flash data, the event data SHOULD be “ACPI DATA”. + * For BIS code, the event data SHOULD be “BIS CODE”. + * For embedded option ROMs, the event data SHOULD be “Embedded UEFI Driver”. + */ +public class EvPostCode { + /** Event Description. */ + private String codeInfo = ""; + /** String type flag. */ + private boolean bisString = false; + /** Firmware object. */ + private UefiFirmware blob = null; + + /** + * EcPostCode constructor. + * @param postCode byte array holding the post code content. + */ + public EvPostCode(final byte[] postCode) { + // 2 ways post code has been implemented, check for the ascii string first + if (isAscii(postCode)) { + String info = new String(postCode, StandardCharsets.UTF_8); + codeInfo = info; + bisString = true; + } else { + blob = new UefiFirmware(postCode); + } + } + + /** + * Returns the UEFI Defined Firmware Blob information. + * @return UEFI Defined Firmware Blob information. + */ + public UefiFirmware getfirmwareBlob() { + return blob; + } + + /** + * Flag set to true if Post Code is a string. + * @return true if Post Code is a string. + */ + public boolean isString() { + return bisString; + } + + /** + * Returns a human readable string of the Post Code information. + * @return human readable string. + */ + public String toString() { + if (bisString) { + return codeInfo; + } + return blob.toString(); + } + + /** + * Determines if the byte array is a string. + * @param postCode byte array input. + * @return true if byte array is a string. + */ + public static boolean isAscii(final byte[] postCode) { + boolean bisAscii = true; + for (byte b : postCode) { + if (!Character.isDefined(b)) { + return false; + } + } + return bisAscii; + } +} diff --git a/HIRS_Utils/src/main/java/hirs/tpm/eventlog/events/EvSCrtmContents.java b/HIRS_Utils/src/main/java/hirs/tpm/eventlog/events/EvSCrtmContents.java new file mode 100644 index 00000000..761d9c93 --- /dev/null +++ b/HIRS_Utils/src/main/java/hirs/tpm/eventlog/events/EvSCrtmContents.java @@ -0,0 +1,41 @@ +package hirs.tpm.eventlog.events; + +import java.nio.charset.StandardCharsets; + +/** + * Class to process the PC Client Firmware profile defined EV_S_CRTM_CONTENTS event. + */ +public class EvSCrtmContents { + + private String description = ""; + + /** + * Constructor that takes in the event data and waits to be called. + * @param event byte array holding the event content data. + */ + public EvSCrtmContents(final byte[] event) { + scrtmContents(event); + } + + /** + * Checks if event data is null and if not it converts to a String. + * @param event byte array holding the event data. + * @return String contents contained within the event. + */ + public String scrtmContents(final byte[] event) { + if (event == null) { + description = "invalid content event data"; + } else { + description = new String(event, StandardCharsets.UTF_8); + } + return description; + } + + /** + * Human readable string contained within the CRTM Contents event. + * @return Human readable string. + */ + public String toString() { + return description; + } +} diff --git a/HIRS_Utils/src/main/java/hirs/tpm/eventlog/events/EvSCrtmVersion.java b/HIRS_Utils/src/main/java/hirs/tpm/eventlog/events/EvSCrtmVersion.java new file mode 100644 index 00000000..f0364aeb --- /dev/null +++ b/HIRS_Utils/src/main/java/hirs/tpm/eventlog/events/EvSCrtmVersion.java @@ -0,0 +1,60 @@ +package hirs.tpm.eventlog.events; + +import java.io.UnsupportedEncodingException; + +import hirs.tpm.eventlog.uefi.UefiConstants; +import hirs.tpm.eventlog.uefi.UefiGuid; +import hirs.utils.HexUtils; + +/** + * Class to process the PC Client Firmware profile defined EV_S_CRTM_VERSION event. + */ +public class EvSCrtmVersion { + + private String description = ""; + + /** + * Constructor that takes in the event data and waits to be called. + * @param event byte array holding the event content data. + * @throws UnsupportedEncodingException if parsing issues exist. + */ + public EvSCrtmVersion(final byte[] event) throws UnsupportedEncodingException { + sCrtmVersion(event); + } + + /** + * Checks if event data is null and if not it converts to a String. + * @param data byte array holding the vent content. + * @throws UnsupportedEncodingException if parsing issues exist. + * @return String representation of the version. + */ + public String sCrtmVersion(final byte[] data) throws UnsupportedEncodingException { + UefiGuid guid = null; + if (data == null) { + description = "invalid content event data"; + } else { + if (data.length == UefiConstants.SIZE_16) { + if (UefiGuid.isValidUUID(data)) { + guid = new UefiGuid(data); + String guidInfo = guid.toStringNoLookup(); + description = " SCRM Version = " + guidInfo; + } + } else if (data.length < UefiConstants.SIZE_4) { + description = HexUtils.byteArrayToHexString(data); + } else if (EvPostCode.isAscii(data)) { + description = new String(data, "UTF-8"); + } else { + description = "Unknown Version format"; + } + } + return (description); + } + + /** + * Return function to send data to the toString. + * @return String representation of the version. + */ + public String toString() { + return description; + } +} diff --git a/HIRS_Utils/src/main/java/hirs/tpm/eventlog/events/package-info.java b/HIRS_Utils/src/main/java/hirs/tpm/eventlog/events/package-info.java new file mode 100644 index 00000000..c50fce17 --- /dev/null +++ b/HIRS_Utils/src/main/java/hirs/tpm/eventlog/events/package-info.java @@ -0,0 +1,6 @@ +/** + * Non-persistant classes related to TGC Event Logs. + */ + +package hirs.tpm.eventlog.events; + diff --git a/HIRS_Utils/src/main/java/hirs/tpm/eventlog/uefi/UefiConstants.java b/HIRS_Utils/src/main/java/hirs/tpm/eventlog/uefi/UefiConstants.java index 33906100..44f44339 100644 --- a/HIRS_Utils/src/main/java/hirs/tpm/eventlog/uefi/UefiConstants.java +++ b/HIRS_Utils/src/main/java/hirs/tpm/eventlog/uefi/UefiConstants.java @@ -19,16 +19,30 @@ public final class UefiConstants { public static final int SIZE_5 = 5; /** 8 byte size. */ public static final int SIZE_8 = 8; + /** 12 byte size. */ + public static final int SIZE_12 = 12; + /** 15 byte size. */ + public static final int SIZE_15 = 15; /** 16 byte size. */ public static final int SIZE_16 = 16; /** 20 byte size. */ public static final int SIZE_20 = 20; + /** 21 byte size. */ + public static final int SIZE_21 = 21; + /** 22 byte size. */ + public static final int SIZE_22 = 22; + /** 23 byte size. */ + public static final int SIZE_23 = 23; + /** 24 byte size. */ + public static final int SIZE_24 = 24; /** 28 byte size. */ public static final int SIZE_28 = 28; /** 32 byte size. */ public static final int SIZE_32 = 32; /** 40 byte size. */ public static final int SIZE_40 = 40; + /** 128 byte size. */ + public static final int SIZE_128 = 128; /** 256 byte size. */ public static final int SIZE_256 = 256; /** 1 byte offset. */ @@ -47,6 +61,10 @@ public final class UefiConstants { public static final int OFFSET_16 = 16; /** 20 byte offset. */ public static final int OFFSET_20 = 20; + /** 21 byte offset. */ + public static final int OFFSET_21 = 21; + /** 22 byte offset. */ + public static final int OFFSET_22 = 22; /** 24 byte offset. */ public static final int OFFSET_24 = 24; /** 28 byte offset. */ diff --git a/HIRS_Utils/src/test/java/hirs/tpm/eventlog/TCGEventLogProcessorTest.java b/HIRS_Utils/src/test/java/hirs/tpm/eventlog/TCGEventLogProcessorTest.java index eb71af0a..cbbdbb56 100644 --- a/HIRS_Utils/src/test/java/hirs/tpm/eventlog/TCGEventLogProcessorTest.java +++ b/HIRS_Utils/src/test/java/hirs/tpm/eventlog/TCGEventLogProcessorTest.java @@ -2,14 +2,16 @@ package hirs.tpm.eventlog; import java.io.IOException; import java.io.InputStream; +import java.security.NoSuchAlgorithmException; +import java.security.cert.CertificateException; import java.util.Arrays; -import java.util.List; -import java.util.Set; +//import java.util.List; +//import java.util.Set; import org.apache.commons.io.IOUtils; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; -import org.hibernate.Session; +//import org.hibernate.Session; import org.testng.Assert; @@ -17,24 +19,18 @@ import org.testng.annotations.AfterClass; import org.testng.annotations.BeforeClass; import org.testng.annotations.Test; -/* -import org.junit.Test; -import org.junit.AfterClass; -import org.junit.Assert; -import org.junit.BeforeClass; -*/ - -import hirs.data.persist.Baseline; -import hirs.data.persist.Digest; -import hirs.data.persist.SpringPersistenceTest; -import hirs.data.persist.TpmWhiteListBaseline; -import hirs.utils.HexUtils; +//import hirs.data.persist.Baseline; +//import hirs.data.persist.Digest; +//import hirs.data.persist.SpringPersistenceTest; +//import hirs.data.persist.TpmWhiteListBaseline; +//import hirs.utils.HexUtils; /** * Class for testing TCG Event Log processing. */ -public class TCGEventLogProcessorTest extends SpringPersistenceTest { - private static final String DEFAULT_EVENT_LOG = "/tcgeventlog/TpmLog.bin"; +//public class TCGEventLogProcessorTest extends SpringPersistenceTest { +public class TCGEventLogProcessorTest { + private static final String DEFAULT_EVENT_LOG = "/tcgeventlog/TpmLog.bin"; private static final String DEFAULT_EXPECTED_PCRS = "/tcgeventlog/TpmLogExpectedPcrs.txt"; private static final String SHA1_EVENT_LOG = "/tcgeventlog/TpmLogSHA1.bin"; private static final String SHA1_EXPECTED_PCRS = "/tcgeventlog/TpmLogSHA1ExpectedPcrs.txt"; @@ -64,6 +60,7 @@ public class TCGEventLogProcessorTest extends SpringPersistenceTest { * removing all Baseline objects. */ // @AfterMethod + /* public final void resetTestState() { LOGGER.debug("reset test state"); LOGGER.debug("deleting all baselines"); @@ -77,13 +74,16 @@ public class TCGEventLogProcessorTest extends SpringPersistenceTest { LOGGER.debug("all baselines removed"); session.getTransaction().commit(); } - +*/ /** - * Tests the processing of a cryto agile event log. + * Tests the processing of a crypto agile event log. * @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 testCryptoAgileTCGEventLog() throws IOException { + public final void testCryptoAgileTCGEventLog() throws IOException, CertificateException, + NoSuchAlgorithmException { LOGGER.debug("Testing the parsing of a Crypto Agile formatted TCG Event Log"); InputStream log, pcrs; boolean testPass = true; @@ -116,15 +116,18 @@ public class TCGEventLogProcessorTest extends SpringPersistenceTest { /** * Tests the processing of a SHA1 formatted Event log. * @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 testSHA1TCGEventLog() throws IOException { + public final void testSHA1TCGEventLog() throws IOException, CertificateException, + NoSuchAlgorithmException { LOGGER.debug("Testing the parsing of a SHA1 formated TCG Event Log"); InputStream log, pcrs; boolean testPass = true; log = this.getClass().getResourceAsStream(SHA1_EVENT_LOG); byte[] rawLogBytes = IOUtils.toByteArray(log); - TCGEventLogProcessor tlp = new TCGEventLogProcessor(rawLogBytes); + TCGEventLogProcessor tlp = new TCGEventLogProcessor(rawLogBytes); String[] pcrFromLog = tlp.getExpectedPCRValues(); pcrs = this.getClass().getResourceAsStream(SHA1_EXPECTED_PCRS); Object[] pcrObj = IOUtils.readLines(pcrs).toArray(); @@ -152,7 +155,8 @@ public class TCGEventLogProcessorTest extends SpringPersistenceTest { * Tests TPM Baseline creation from a EventLog. * @throws IOException when processing the test fails */ - @Test + //@Test + /* public final void testTPMBaselineCreate() throws IOException { LOGGER.debug("Create and save TPM baseline from TCG Event Log test started"); InputStream log; @@ -182,4 +186,5 @@ public class TCGEventLogProcessorTest extends SpringPersistenceTest { Assert.assertTrue(testPass); LOGGER.debug("OK. Create and save TPM baseline from TCG Event Log was a success"); } + */ } 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 new file mode 100644 index 00000000..7e57d1dd --- /dev/null +++ b/HIRS_Utils/src/test/java/hirs/tpm/eventlog/events/TCGEventLogEventsTest.java @@ -0,0 +1,160 @@ +package hirs.tpm.eventlog.events; + +import java.io.IOException; +import java.security.NoSuchAlgorithmException; +import java.security.cert.CertificateException; +import java.util.ArrayList; + +import org.apache.commons.io.IOUtils; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.testng.Assert; +import org.testng.annotations.AfterClass; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.Test; + +import hirs.tpm.eventlog.TCGEventLogProcessorTest; +import hirs.utils.HexUtils; +import hirs.tpm.eventlog.uefi.UefiGuid; +import hirs.tpm.eventlog.uefi.UefiPartition; + +/** + * Class for testing TCG Event Log Event processing. + */ +public class TCGEventLogEventsTest { + // 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"; + private static final String EVENT_GPT_PARTITION + = "/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(TCGEventLogProcessorTest.class); + + /** + * Initializes a SessionFactory. + */ + @BeforeClass + public static final void setup() { + LOGGER.debug("retrieving session factory"); + + } + + /** + * Closes the SessionFactory from setup. + */ + @AfterClass + public static final void tearDown() { + 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 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 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 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"); + } +} diff --git a/HIRS_Utils/src/test/java/hirs/tpm/eventlog/events/package-info.java b/HIRS_Utils/src/test/java/hirs/tpm/eventlog/events/package-info.java new file mode 100644 index 00000000..c50fce17 --- /dev/null +++ b/HIRS_Utils/src/test/java/hirs/tpm/eventlog/events/package-info.java @@ -0,0 +1,6 @@ +/** + * Non-persistant classes related to TGC Event Logs. + */ + +package hirs.tpm.eventlog.events; + diff --git a/HIRS_Utils/src/test/resources/tcgeventlog/events/EvBootServicesApplication.txt b/HIRS_Utils/src/test/resources/tcgeventlog/events/EvBootServicesApplication.txt new file mode 100644 index 00000000..802c5d14 --- /dev/null +++ b/HIRS_Utils/src/test/resources/tcgeventlog/events/EvBootServicesApplication.txt @@ -0,0 +1 @@ +1820d45800000000e0b405000000000000000000000000002c00000000000000040714002ce2edb630defa45bb09ca202c1654b7040614001ae3e1159d9f844c82fb1a707fc0f63b7fff0400 diff --git a/HIRS_Utils/src/test/resources/tcgeventlog/events/EvEfiGptPartition.txt b/HIRS_Utils/src/test/resources/tcgeventlog/events/EvEfiGptPartition.txt new file mode 100644 index 00000000..1cd7e09d --- /dev/null +++ b/HIRS_Utils/src/test/resources/tcgeventlog/events/EvEfiGptPartition.txt @@ -0,0 +1 @@ +4546492050415254000001005c000000a071310c000000000100000000000000af44f21b0000000022000000000000008e44f21b000000006fe7c34e23793e4cb040e8080f1b888302000000000000008000000080000000d0be05490500000000000000a4bb94ded106404da16abfd50179d6ac8787cc4223db454e9981701adc801dc70008000000000000ffa70f000000000001000000000000804200610073006900630020006400610074006100200070006100720074006900740069006f006e00000000000000000000000000000000000000000000000000000000000000000028732ac11ff8d211ba4b00a0c93ec93b3c62a78c1e04ab4f8c12f49a86b85d7300a80f0000000000ffc712000000000000000000000000804500460049002000730079007300740065006d00200070006100720074006900740069006f006e00000000000000000000000000000000000000000000000000000000000000000016e3c9e35c0bb84d817df92df00215aeffcf90d80c32454fb6cfa4d8bee6d9cb00c8120000000000ffc71a000000000000000000000000804d006900630072006f0073006f0066007400200072006500730065007200760065006400200070006100720074006900740069006f006e0000000000000000000000000000000000a2a0d0ebe5b9334487c068b6b72699c71c4c250c124b884ab88442a31866a34800c81a0000000000ff3ff81a0000000000000000000000004200610073006900630020006400610074006100200070006100720074006900740069006f006e000000000000000000000000000000000000000000000000000000000000000000a4bb94ded106404da16abfd50179d6ac92e459bc0fb29549b1488ded030c7ec20040f81a00000000ff3ff21b0000000001000000000000804200610073006900630020006400610074006100200070006100720074006900740069006f006e000000a70afc7f00007051864ba8020000c091dc4ba8020000bf3a758076450000 diff --git a/HIRS_Utils/src/test/resources/tcgeventlog/events/EvEfiSpecId.txt b/HIRS_Utils/src/test/resources/tcgeventlog/events/EvEfiSpecId.txt new file mode 100644 index 00000000..841a1be6 --- /dev/null +++ b/HIRS_Utils/src/test/resources/tcgeventlog/events/EvEfiSpecId.txt @@ -0,0 +1 @@ +53706563204944204576656e743033000000000000020002010000000b00200000 diff --git a/HIRS_Utils/src/test/resources/tcgeventlog/events/EvHandoffTables.txt b/HIRS_Utils/src/test/resources/tcgeventlog/events/EvHandoffTables.txt new file mode 100644 index 00000000..ef759b94 --- /dev/null +++ b/HIRS_Utils/src/test/resources/tcgeventlog/events/EvHandoffTables.txt @@ -0,0 +1 @@ +01000000000000004415fdf294972c4a992ee5bbcf20e3940000676300000000 \ No newline at end of file diff --git a/HIRS_Utils/src/test/resources/tcgeventlog/events/EvPostCode.txt b/HIRS_Utils/src/test/resources/tcgeventlog/events/EvPostCode.txt new file mode 100644 index 00000000..b76c680f --- /dev/null +++ b/HIRS_Utils/src/test/resources/tcgeventlog/events/EvPostCode.txt @@ -0,0 +1 @@ +414350492044415441 diff --git a/tools/tcg_rim_tool/generated_swidTag.swidtag b/tools/tcg_rim_tool/generated_swidTag.swidtag new file mode 100644 index 00000000..e50475ab --- /dev/null +++ b/tools/tcg_rim_tool/generated_swidTag.swidtag @@ -0,0 +1,42 @@ + + + + + + + + + + + + jfwo1CF30jTNX7m/j85Avnt0EedV/QJIsRUZnaOY+Dg= + + + VqUHbt1UqkxlLHVkTOlQs54KWjv5IPKzSCxrsPb8kGjaj5XjHkc1Z/h88znIIMTdCLcyrKgNEXS4 +9EHI9nn9LmwXEd/ozKWd8adu6wLdxKj6uIfd0HaCLFrVlnf/b16xO9AW6wp5pLmXwoFi7zBXXJrn +F9MDKy55mXkxb/Z5RUC3IKqsoz+EuKjs6d+yhtb1EQtpJD2dZj23+VjMH4gXxEerDNR1PiPhma/i +QMFa1hwSO7AuasYPy0WCRIgrJ5ZL5x2ZoaSIdE2TsCqnStVL+KLZeMWNCqw4k89hsuELW7Azrl57 +Vm2qzPok0svrB1K4QyZdyK2bnG1QY3Fip5Jdmg== + + + CN=example.RIM.signer,OU=PCClient,O=Example,ST=VA,C=US + MIIDYTCCAkmgAwIBAgIJAPB+r6VBhBn4MA0GCSqGSIb3DQEBCwUAMFMxCzAJBgNVBAYTAlVTMQsw +CQYDVQQIDAJWQTEQMA4GA1UECgwHRXhhbXBsZTERMA8GA1UECwwIUENDbGllbnQxEjAQBgNVBAMM +CUV4YW1wbGVDQTAeFw0yMDAyMTAxODE1MzRaFw0yOTEyMTkxODE1MzRaMFwxCzAJBgNVBAYTAlVT +MQswCQYDVQQIDAJWQTEQMA4GA1UECgwHRXhhbXBsZTERMA8GA1UECwwIUENDbGllbnQxGzAZBgNV +BAMMEmV4YW1wbGUuUklNLnNpZ25lcjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKd1 +lWGkSRuxAAY2wHag2GVxUk1dZx2PTpfQOflvLeccAVwa8mQhlsRERq+QK8ilj8Xfqs44/nBaccZD +OjdfIxIUCMfwhGXjxCaqZbgTucNsExDnu4arTGraoAwzHg0cVLiKT/Cxj9NL4dcMgxRXsPdHfXb0 +923C7xYd2t2qfW05umgaj7qeQl6c68CFNsGX4JA8rWFQZvvGx5DGlK4KTcjPuQQINs5fxasNKqLY +2hq+z82x/rqwr2hmyizD6FpFSyIABPEMPfB036GEhRwu1WEMkq8yIp2jgRUoFYke9pB3ph9pVow0 +Hh4mNFSKD4pP41VSKY1nus83mdkuukPy5o0CAwEAAaMvMC0wCQYDVR0TBAIwADALBgNVHQ8EBAMC +BsAwEwYDVR0lBAwwCgYIKwYBBQUHAwMwDQYJKoZIhvcNAQELBQADggEBAGuJ+dasb3/Mb7TBJ1Oe +al5ISq8d2LQD5ke5qnjgSQWKXfQ9fcUy3dWnt3Oked/i8B/Tyk3jCdTZJU3J3iRNgTqFfMLP8rU1 +w2tPYBjjuPKiiK4YRBHPxtFxPdOL1BPmL4ZzNs33Lv6H0m4aff9p6QpMclX5b/CRjl+80JWRLiLj +U3B0CejZB9dJrPr9SBaC31cDoeTpja9Cl86ip7KkqrZZIYeMuNF6ucWyWtjrW2kr3UhmEy8x/6y4 +KigsK8sBwmNv4N2Pu3RppeIcpjYj5NVA1hwRA4eeMgJp2u+urm3l1oo1UNX1HsSSBHp1Owc9zZLm +07Pl8T46kpIA4sroCAU= + + + +