mirror of
https://github.com/nsacyber/HIRS.git
synced 2025-04-07 19:34:27 +00:00
[222] Added TCG Event Log Processing that converts TCG Event Logs to HIRS T… (#223)
* Added TCG Event Log Processing that converts TCG Event Logs to HIRS TPM Baselines * Some minor formating, syntax and code refactoring updates. * Updated checkstyle failures. * String format was missing additional %s. Co-authored-by: Cyrus <24922493+cyrus-dev@users.noreply.github.com>
This commit is contained in:
parent
6838a38fbc
commit
9a835d8923
@ -0,0 +1,138 @@
|
||||
package hirs.tpm.eventlog;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import hirs.utils.HexUtils;
|
||||
|
||||
/**
|
||||
* Class to handle the "Crypto Agile" Format for TCG Event Logs as defined in the
|
||||
* TCG Platform Firmware Profile (PFP).
|
||||
* The Format can provide multiple digests with different algorithm,
|
||||
* however currently on SHA256 is supported.
|
||||
* All other are currently ignored.
|
||||
*/
|
||||
public class CryptoAgileEventLog implements TCGEventLog {
|
||||
/**
|
||||
* SHA256 length = 24 bytes.
|
||||
*/
|
||||
private static final int PCR_LENGTH = TpmPcrEvent.SHA256_LENGTH;
|
||||
/**
|
||||
* Each PCR bank holds 24 registers.
|
||||
*/
|
||||
private static final int PCR_COUNT = 24;
|
||||
/**
|
||||
* PFP defined EV_NO_ACTION identifier.
|
||||
*/
|
||||
private static final int NO_ACTION_EVENT = 0x00000003;
|
||||
/**
|
||||
* 2 dimensional array holding the PCR values.
|
||||
*/
|
||||
private byte[][] pcrList = new byte[PCR_COUNT][PCR_LENGTH];
|
||||
/**
|
||||
* List of parsed events within the log.
|
||||
*/
|
||||
private ArrayList<TpmPcrEvent> eventList = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param rawlog the entire tcg log
|
||||
* @throws IOException if the input stream cannot access the log data
|
||||
*/
|
||||
public CryptoAgileEventLog(final byte[] rawlog) throws IOException {
|
||||
ByteArrayInputStream is = new ByteArrayInputStream(rawlog);
|
||||
// process the EfiSpecId Event in SHA1 format per the PFP
|
||||
TpmPcrEvent1 idEvent = new TpmPcrEvent1(is);
|
||||
eventList.add(idEvent);
|
||||
// put all events into an event list for further processing
|
||||
while (is.available() > 0) { // All other events should be Crypto agile
|
||||
eventList.add(new TpmPcrEvent2(is));
|
||||
}
|
||||
calculatePCRValues();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a single PCR value given an index (PCR Number).
|
||||
*/
|
||||
@Override
|
||||
public String[] getExpectedPCRValues() {
|
||||
String[] pcrs = new String[PCR_COUNT];
|
||||
for (int i = 0; i < PCR_COUNT; i++) {
|
||||
pcrs[i] = HexUtils.byteArrayToHexString(pcrList[i]);
|
||||
}
|
||||
return pcrs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all 24 PCR values for display purposes.
|
||||
*
|
||||
* @param index pcr index
|
||||
* @return Returns an array of strings for all 24 PCRs
|
||||
*/
|
||||
@Override
|
||||
public String getExpectedPCRValue(final int index) {
|
||||
return HexUtils.byteArrayToHexString(pcrList[index]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the "Expected Values for TPM PCRs based upon Event digests in the Event Log.
|
||||
* Uses the algorithm and eventList passed into the constructor.
|
||||
*
|
||||
* @return a 2 dimensional bye array holding the hashes of the PCRs.
|
||||
*/
|
||||
private void calculatePCRValues() {
|
||||
byte[] extendedPCR = null;
|
||||
for (int i = 0; i < PCR_COUNT; i++) { // Initialize the PCRlist array
|
||||
System.arraycopy(HexUtils.hexStringToByteArray(
|
||||
"0000000000000000000000000000000000000000000000000000000000000000"),
|
||||
0, pcrList[i], 0, PCR_LENGTH);
|
||||
}
|
||||
for (TpmPcrEvent currentEvent : eventList) {
|
||||
if (currentEvent.getPcrIndex() >= 0) { // Ignore NO_EVENTS which can have a PCR=-1
|
||||
try {
|
||||
if (currentEvent.getEventType() != NO_ACTION_EVENT) {
|
||||
// Don't include EV_NO_ACTION
|
||||
extendedPCR = extendPCRsha256(pcrList[currentEvent.getPcrIndex()],
|
||||
currentEvent.getEventDigest());
|
||||
System.arraycopy(extendedPCR, 0, pcrList[currentEvent.getPcrIndex()],
|
||||
0, PCR_LENGTH);
|
||||
}
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Extends a sha256 hash with a hash of new data.
|
||||
*
|
||||
* @param currentValue byte array holding the current hash value
|
||||
* @param newEvent byte array holding the value to extend
|
||||
* @return new hash value
|
||||
* @throws NoSuchAlgorithmException if hash algorithm is not supported.
|
||||
*/
|
||||
private byte[] extendPCRsha256(final byte[] currentValue, final byte[] newEvent)
|
||||
throws NoSuchAlgorithmException {
|
||||
return sha256hash(
|
||||
HexUtils.hexStringToByteArray(HexUtils.byteArrayToHexString(currentValue)
|
||||
+ HexUtils.byteArrayToHexString(newEvent)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a sha356 hash of a given byte array.
|
||||
*
|
||||
* @param blob byte array hold the value to hash.
|
||||
* @return byte array holding the hash of the input array.
|
||||
* @throws NoSuchAlgorithmException if hash algorithm is not supported.
|
||||
*/
|
||||
private byte[] sha256hash(final byte[] blob) throws NoSuchAlgorithmException {
|
||||
MessageDigest md = MessageDigest.getInstance("SHA-256");
|
||||
md.update(blob);
|
||||
return md.digest();
|
||||
}
|
||||
}
|
134
HIRS_Utils/src/main/java/hirs/tpm/eventlog/SHA1EventLog.java
Normal file
134
HIRS_Utils/src/main/java/hirs/tpm/eventlog/SHA1EventLog.java
Normal file
@ -0,0 +1,134 @@
|
||||
package hirs.tpm.eventlog;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import hirs.utils.HexUtils;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
/**
|
||||
* Class to handle the "SHA1" Format for TCG Event Logs.
|
||||
* "SHA1" Format is defined in the TCG Platform Firmware Profile (PFP).
|
||||
* This is to support older versions of UEFI Firmware or OS that create logs with SHA1.
|
||||
*/
|
||||
public class SHA1EventLog implements TCGEventLog {
|
||||
private static final Logger LOGGER
|
||||
= LogManager.getLogger(TCGEventLog.class);
|
||||
/**
|
||||
* SHA256 length = 24 bytes.
|
||||
*/
|
||||
private static final int PCR_LENGTH = TpmPcrEvent.SHA1_LENGTH;
|
||||
/**
|
||||
* Each PCR bank holds 24 registers.
|
||||
*/
|
||||
private static final int PCR_COUNT = 24;
|
||||
/**
|
||||
* PFP defined EV_NO_ACTION identifier.
|
||||
*/
|
||||
private static final int NO_ACTION_EVENT = 0x00000003;
|
||||
/**
|
||||
* List of parsed events within the log.
|
||||
*/
|
||||
private final ArrayList<TpmPcrEvent> eventList = new ArrayList<TpmPcrEvent>();
|
||||
/**
|
||||
* 2 dimensional array holding the PCR values.
|
||||
*/
|
||||
private final byte[][] pcrList1 = new byte[PCR_COUNT][PCR_LENGTH];
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param rawlog the entire tcg log
|
||||
* @throws IOException if the inspur stream cannot access the log data
|
||||
*/
|
||||
public SHA1EventLog(final byte[] rawlog) throws IOException {
|
||||
ByteArrayInputStream is = new ByteArrayInputStream(rawlog);
|
||||
// put all events into an event list for further processing
|
||||
while (is.available() > 0) {
|
||||
eventList.add(new TpmPcrEvent1(is));
|
||||
}
|
||||
calculatePcrValues();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all 24 PCR values for display purposes.
|
||||
*
|
||||
* @return Returns an array of strings representing the expected hash values for all 24 PCRs
|
||||
*/
|
||||
public String[] getExpectedPCRValues() {
|
||||
String[] pcrs = new String[PCR_COUNT];
|
||||
for (int i = 0; i < PCR_COUNT; i++) {
|
||||
pcrs[i] = HexUtils.byteArrayToHexString(pcrList1[i]);
|
||||
}
|
||||
return pcrs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a single PCR value given an index (PCR Number).
|
||||
*
|
||||
* @param index pcr index
|
||||
* @return String representing the PCR contents
|
||||
*/
|
||||
public String getExpectedPCRValue(final int index) {
|
||||
return HexUtils.byteArrayToHexString(pcrList1[index]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the "Expected Values for TPM PCRs based upon Event digests in the Event Log.
|
||||
* Uses the algorithm and eventList passed into the constructor,
|
||||
*/
|
||||
private void calculatePcrValues() {
|
||||
byte[] extendedPCR = null;
|
||||
for (int i = 0; i < PCR_COUNT; i++) { // Initialize the PCRlist1 array
|
||||
System.arraycopy(HexUtils.hexStringToByteArray(
|
||||
"0000000000000000000000000000000000000000"),
|
||||
0, pcrList1[i], 0, PCR_LENGTH);
|
||||
}
|
||||
for (TpmPcrEvent currentEvent : eventList) {
|
||||
if (currentEvent.getPcrIndex() >= 0) { // Ignore NO_EVENTS which can have a PCR=-1
|
||||
try {
|
||||
if (currentEvent.getEventType() != NO_ACTION_EVENT) {
|
||||
// Don't include EV_NO_ACTION event
|
||||
extendedPCR = extendPCRsha1(pcrList1[currentEvent.getPcrIndex()],
|
||||
currentEvent.getEventDigest());
|
||||
System.arraycopy(extendedPCR, 0, pcrList1[currentEvent.getPcrIndex()],
|
||||
0, currentEvent.getDigestLength());
|
||||
}
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
LOGGER.error(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Extends a sha1 hash with a hash of new data.
|
||||
*
|
||||
* @param currentValue value to extend
|
||||
* @param newEvent value to extend with
|
||||
* @return new hash resultant hash
|
||||
* @throws NoSuchAlgorithmException if hash algorithm not supported
|
||||
*/
|
||||
private byte[] extendPCRsha1(final byte[] currentValue, final byte[] newEvent)
|
||||
throws NoSuchAlgorithmException {
|
||||
return sha1hash(HexUtils.hexStringToByteArray(HexUtils.byteArrayToHexString(currentValue)
|
||||
+ HexUtils.byteArrayToHexString(newEvent)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a sha1 hash of a given byte array.
|
||||
*
|
||||
* @param blob byte array of data to hash
|
||||
* @return byte array holding the hash of the input array
|
||||
* @throws NoSuchAlgorithmException id hash algorithm not supported
|
||||
*/
|
||||
private byte[] sha1hash(final byte[] blob) throws NoSuchAlgorithmException {
|
||||
MessageDigest md = MessageDigest.getInstance("SHA1");
|
||||
md.update(blob);
|
||||
return md.digest();
|
||||
}
|
||||
}
|
16
HIRS_Utils/src/main/java/hirs/tpm/eventlog/TCGEventLog.java
Normal file
16
HIRS_Utils/src/main/java/hirs/tpm/eventlog/TCGEventLog.java
Normal file
@ -0,0 +1,16 @@
|
||||
package hirs.tpm.eventlog;
|
||||
|
||||
/**
|
||||
* Interface for handling different formats of TCG Event logs.
|
||||
*/
|
||||
public interface TCGEventLog {
|
||||
/** Retrieves a all expected PCR values.
|
||||
* @return String array holding all PCR Values
|
||||
*/
|
||||
String[] getExpectedPCRValues();
|
||||
/** Retrieves a single expected PCR values.
|
||||
* @param index the PCR reference
|
||||
* @return a String holding an expected PCR value
|
||||
*/
|
||||
String getExpectedPCRValue(int index);
|
||||
}
|
@ -0,0 +1,126 @@
|
||||
package hirs.tpm.eventlog;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.math.BigInteger;
|
||||
|
||||
import hirs.data.persist.TPMMeasurementRecord;
|
||||
import hirs.data.persist.TpmWhiteListBaseline;
|
||||
import hirs.utils.HexUtils;
|
||||
import hirs.data.persist.Digest;
|
||||
import hirs.data.persist.DigestAlgorithm;;
|
||||
|
||||
/**
|
||||
* Class for parsing a TCG EventLogs (both SHA1 and Crypto Agile Formats).
|
||||
* Also produces a TPM Baseline using he digests within the event log.
|
||||
* 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.
|
||||
*/
|
||||
private String algorithm = "SHA256";
|
||||
/**
|
||||
* PFP defined EV_NO_ACTION identifier.
|
||||
*/
|
||||
private static final int NO_ACTION_EVENT = 0x00000003;
|
||||
/**
|
||||
* Parsed event log array.
|
||||
*/
|
||||
private TCGEventLog tcgLog = null;
|
||||
/**
|
||||
* EV_NO_ACTION signature offset.
|
||||
*/
|
||||
private static final int SIG_OFFSET = 32;
|
||||
/**
|
||||
* TEV_NO_ACTION signature size.
|
||||
*/
|
||||
private static final int SIG_SIZE = 16;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param rawLog the byte array holding the contents of the TCG Event Log
|
||||
* @throws IOException if there is a parsing error
|
||||
*/
|
||||
public TCGEventLogProcessor(final byte[] rawLog) throws IOException {
|
||||
if (isLogCrytoAgile(rawLog)) {
|
||||
tcgLog = new CryptoAgileEventLog(rawLog);
|
||||
} else {
|
||||
tcgLog = new SHA1EventLog(rawLog);
|
||||
algorithm = "SHA";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all 24 PCR values for display purposes.
|
||||
*
|
||||
* @return Returns an array of strings representing the expected hash values for all 24 PCRs
|
||||
*/
|
||||
public String[] getExpectedPCRValues() {
|
||||
return tcgLog.getExpectedPCRValues();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a single PCR value given an index (PCR Number).
|
||||
*
|
||||
* @param index the PCR index
|
||||
* @return String representing the PCR contents
|
||||
*/
|
||||
public String getExpectedPCRValue(final int index) {
|
||||
return tcgLog.getExpectedPCRValue(index);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a TPM baseline using the expected PCR Values.
|
||||
* Expected PCR Values were Calculated from the EventLog (RIM Support file).
|
||||
*
|
||||
* @param name name to call the TPM Baseline
|
||||
* @return whitelist baseline
|
||||
*/
|
||||
public TpmWhiteListBaseline createTPMBaseline(final String name) {
|
||||
TpmWhiteListBaseline baseline = new TpmWhiteListBaseline(name);
|
||||
TPMMeasurementRecord record = null;
|
||||
String pcrValue = "";
|
||||
for (int i = 0; i < TpmPcrEvent.PCR_COUNT; i++) {
|
||||
if (algorithm.compareToIgnoreCase("SHA1") == 0) { // Log Was SHA1 Format
|
||||
pcrValue = tcgLog.getExpectedPCRValue(i);
|
||||
byte[] hexValue = HexUtils.hexStringToByteArray(pcrValue);
|
||||
final Digest hash = new Digest(DigestAlgorithm.SHA1, hexValue);
|
||||
record = new TPMMeasurementRecord(i, hash);
|
||||
} else { // Log was Crypto Agile, currently assumes SHA256
|
||||
pcrValue = tcgLog.getExpectedPCRValue(i);
|
||||
byte[] hexValue = HexUtils.hexStringToByteArray(pcrValue);
|
||||
final Digest hash = new Digest(DigestAlgorithm.SHA256, hexValue);
|
||||
record = new TPMMeasurementRecord(i, hash);
|
||||
}
|
||||
baseline.addToBaseline(record);
|
||||
}
|
||||
return baseline;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if an event is an EfiSpecIdEvent indicating that the log format is crypto agile.
|
||||
* The EfiSpecIdEvent should be the first event in the TCG TPM Event Log.
|
||||
*
|
||||
* @param log The Event Log
|
||||
* @return true if EfiSpecIDEvent is found and indicates that the format is crypto agile
|
||||
* @throws UnsupportedEncodingException
|
||||
*/
|
||||
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);
|
||||
byte[] eventType = HexUtils.leReverseByte(eType);
|
||||
int eventID = new BigInteger(eventType).intValue();
|
||||
if (eventID != NO_ACTION_EVENT) {
|
||||
return false;
|
||||
} // Event Type should be EV_NO_ACTION
|
||||
byte[] signature = new byte[SIG_SIZE];
|
||||
System.arraycopy(log, SIG_OFFSET, signature, 0, SIG_SIZE); // should be "Spec ID Event03"
|
||||
String sig = new String(signature, "UTF-8").substring(0, SIG_SIZE - 1); // remove null char
|
||||
if (sig.equals("Spec ID Event03")) {
|
||||
return true;
|
||||
}
|
||||
return (false);
|
||||
}
|
||||
}
|
196
HIRS_Utils/src/main/java/hirs/tpm/eventlog/TcgTpmtHa.java
Normal file
196
HIRS_Utils/src/main/java/hirs/tpm/eventlog/TcgTpmtHa.java
Normal file
@ -0,0 +1,196 @@
|
||||
package hirs.tpm.eventlog;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
import java.math.BigInteger;
|
||||
|
||||
import hirs.utils.HexUtils;
|
||||
|
||||
/**
|
||||
* Class to for the TCG defined TPMT_HA structure used to support the Crypto Agile Log format.
|
||||
* <p>
|
||||
* typedef struct {
|
||||
* TPMI_ALG_HASH hashAlg;
|
||||
* TPMU_HA digest;
|
||||
* } TPMT_HA;
|
||||
*/
|
||||
public class TcgTpmtHa {
|
||||
/**
|
||||
* TCG Defined Algorithm Identifiers .
|
||||
*/
|
||||
private int hashAlgId = 0;
|
||||
/**
|
||||
* Length of the hash.
|
||||
*/
|
||||
private int hashLength = 0;
|
||||
/**
|
||||
* Human readable name of the hash algorithm.
|
||||
*/
|
||||
private String hashName = "";
|
||||
/**
|
||||
* Hash data.
|
||||
*/
|
||||
private byte[] digest = null;
|
||||
/**
|
||||
* TCG ID for SHA1.
|
||||
*/
|
||||
private static final int TPM_ALG_SHA1 = 0x04;
|
||||
/**
|
||||
* TCG ID for SHA1.
|
||||
*/
|
||||
private static final int TPM_ALG_SHA256 = 0x0B;
|
||||
/**
|
||||
* TCG ID for SHA 384.
|
||||
*/
|
||||
private static final int TPM_ALG_SHA384 = 0x0C;
|
||||
/**
|
||||
* TCG ID for SHA512.
|
||||
*/
|
||||
private static final int TPM_ALG_SHA_512 = 0x0D;
|
||||
/**
|
||||
* TCG ID for Null algorithm.
|
||||
*/
|
||||
private static final int TPM_ALG_NULL = 0x10;
|
||||
/**
|
||||
* TCG ID for SHA1.
|
||||
*/
|
||||
private static final int TPM_ALG_SHA1_LENGTH = 20;
|
||||
/**
|
||||
* TCG ID for SHA1.
|
||||
*/
|
||||
private static final int TPM_ALG_SHA256_LENGH = 32;
|
||||
/**
|
||||
* TCG ID for SHA 384.
|
||||
*/
|
||||
private static final int TPM_ALG_SHA384_LENGTH = 48;
|
||||
/**
|
||||
* TCG ID for SHA512.
|
||||
*/
|
||||
private static final int TPM_ALG_SHA512_LENGTH = 64;
|
||||
/**
|
||||
* TCG ID for Null algorithm.
|
||||
*/
|
||||
private static final int TPM_ALG_NULL_LENGTH = 0;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param is ByteArrayInputStream holding the TcgTPMT_HA structured data
|
||||
* @throws IOException if TPMT_HA structure cannot be parsed
|
||||
*/
|
||||
public TcgTpmtHa(final ByteArrayInputStream is) throws IOException {
|
||||
byte[] algID = new byte[2];
|
||||
is.read(algID);
|
||||
byte[] rAlgID = HexUtils.leReverseByte(algID);
|
||||
hashAlgId = new BigInteger(rAlgID).intValue();
|
||||
hashName = tcgAlgIdtoString(algID[0]);
|
||||
hashLength = tcgAlgLength(algID[0]);
|
||||
digest = new byte[hashLength];
|
||||
is.read(digest);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the TCG defined algorithm identifier.
|
||||
*
|
||||
* @return integer that specifies the algorithm as defined by the TCG
|
||||
*/
|
||||
public int getAlgId() {
|
||||
return hashAlgId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the length of the Hash.
|
||||
*
|
||||
* @return the Hash length
|
||||
*/
|
||||
public int getHashLength() {
|
||||
return hashLength;
|
||||
}
|
||||
|
||||
/**
|
||||
* Readable name of the algorithm.
|
||||
*
|
||||
* @return Hash algorithm name
|
||||
*/
|
||||
public String getHashName() {
|
||||
return hashName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return digest held by the event
|
||||
*/
|
||||
protected byte[] getDigest() {
|
||||
return digest;
|
||||
}
|
||||
|
||||
/**
|
||||
* Readable description of the Algorithm.
|
||||
*
|
||||
* @return Readable Algorithm name
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format("%s hash = %s", hashName, HexUtils.byteArrayToHexString(digest));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the hash name via a lookup.
|
||||
* Lookup based upon section 6.3 for the TPM-Rev-2.0-Part-2-Structures.pdf document.
|
||||
* Only hash algorithms found in Table 7 are used.
|
||||
*
|
||||
* @param algid int to convert to string
|
||||
*/
|
||||
private String tcgAlgIdtoString(final int algid) {
|
||||
String alg;
|
||||
switch (algid) {
|
||||
case TPM_ALG_SHA1:
|
||||
alg = "TPM_ALG_SHA1";
|
||||
break;
|
||||
case TPM_ALG_SHA256:
|
||||
alg = "TPM_ALG_SHA256";
|
||||
break;
|
||||
case TPM_ALG_SHA384:
|
||||
alg = "TPM_ALG_SHA384";
|
||||
break;
|
||||
case TPM_ALG_SHA_512:
|
||||
alg = "TPM_ALG_SHA512";
|
||||
break;
|
||||
case TPM_ALG_NULL:
|
||||
alg = "TPM_ALG_NULL";
|
||||
break;
|
||||
default:
|
||||
alg = "Unknown or invalid Hash";
|
||||
}
|
||||
return alg;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the length of a given TPM ALG Identifier.
|
||||
* (lookup based upon section 6.3 for the TPM-Rev-2.0-Part-2-Structures.pdf document)
|
||||
* Only hash algorithms found in Table 7 are used.
|
||||
*
|
||||
* @param algId TCG defined Algorithm identifier
|
||||
* @return length of hash data in bytes
|
||||
*/
|
||||
private int tcgAlgLength(final int algId) {
|
||||
int length;
|
||||
switch (algId) {
|
||||
case TPM_ALG_SHA1:
|
||||
length = TPM_ALG_SHA1_LENGTH;
|
||||
break;
|
||||
case TPM_ALG_SHA256:
|
||||
length = TPM_ALG_SHA256_LENGH;
|
||||
break;
|
||||
case TPM_ALG_SHA384:
|
||||
length = TPM_ALG_SHA384_LENGTH;
|
||||
break;
|
||||
case TPM_ALG_SHA_512:
|
||||
length = TPM_ALG_SHA512_LENGTH;
|
||||
break;
|
||||
case TPM_ALG_NULL:
|
||||
default:
|
||||
length = TPM_ALG_NULL_LENGTH;
|
||||
}
|
||||
return length;
|
||||
}
|
||||
}
|
218
HIRS_Utils/src/main/java/hirs/tpm/eventlog/TpmPcrEvent.java
Normal file
218
HIRS_Utils/src/main/java/hirs/tpm/eventlog/TpmPcrEvent.java
Normal file
@ -0,0 +1,218 @@
|
||||
package hirs.tpm.eventlog;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
import java.math.BigInteger;
|
||||
|
||||
import hirs.utils.HexUtils;
|
||||
|
||||
/**
|
||||
* Class to process a TCG_PCR_EVENT.
|
||||
* 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_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.
|
||||
*/
|
||||
private int pcrIndex = -1;
|
||||
/**
|
||||
* Event Type (long).
|
||||
*/
|
||||
private long eventType = 0;
|
||||
/**
|
||||
* Event digest.
|
||||
*/
|
||||
private byte[] digest = null;
|
||||
/**
|
||||
* Even 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.
|
||||
*/
|
||||
private int digestLength = 0;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param is ByteArrayInputStream holding the event
|
||||
* @throws IOException when event can't be parsed
|
||||
*/
|
||||
public TpmPcrEvent(final ByteArrayInputStream is) throws IOException {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the digest from a TCG_PCR_EVENT digest field.
|
||||
* This can be SHA1 for older event structures or any algorithm for newer structure.
|
||||
*
|
||||
* @param digestData cryptographic hash
|
||||
*/
|
||||
protected void setEventDigest(final byte[] digestData) {
|
||||
digest = new byte[digestLength];
|
||||
System.arraycopy(digestData, 0, digest, 0, this.digestLength);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the digest from a TCG Event.
|
||||
* This can be SHA1 for older event structures or any algorithm for newer structure.
|
||||
*
|
||||
* @return the digest data for the event
|
||||
*/
|
||||
public byte[] getEventDigest() {
|
||||
byte[] digestCopy = new byte[digestLength];
|
||||
System.arraycopy(digest, 0, digestCopy, 0, this.digestLength);
|
||||
return digestCopy;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the event PCR index value from a TCG Event.
|
||||
*
|
||||
* @param eventIndex TCG Event PCR Index as defined in the PFP
|
||||
*/
|
||||
protected void setPcrIndex(final byte[] eventIndex) {
|
||||
pcrIndex = HexUtils.leReverseInt(eventIndex);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the event index value from a TCG Event.
|
||||
*
|
||||
* @return eventIndex TCG Event Index as defined in the PFP
|
||||
*/
|
||||
public int getPcrIndex() {
|
||||
return pcrIndex;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the EventType for the Event.
|
||||
*
|
||||
* @return event type
|
||||
*/
|
||||
public long getEventType() {
|
||||
return eventType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the version of the TCG Log Event specification pertaining to the log.
|
||||
* only updated if the event is a TCG_EfiSpecIdEvent.
|
||||
*
|
||||
* @return specification version
|
||||
*/
|
||||
public String getSpecVersion() {
|
||||
return version;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the Errata version of the TCG Log Event specification pertaining to the log.
|
||||
* only updated if the event is a TCG_EfiSpecIdEvent).
|
||||
*
|
||||
* @return Errata version
|
||||
*/
|
||||
public String getSpecErrataVersion() {
|
||||
return errata;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the event digest value after processing.
|
||||
*
|
||||
* @param digestData SHA1 or SHA256 digest to set
|
||||
*/
|
||||
protected void setDigest(final byte[] digestData) {
|
||||
digest = new byte[digestLength];
|
||||
System.arraycopy(digestData, 0, digest, 0, digestLength);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the event content after processing.
|
||||
*
|
||||
* @param eventData The PFP defined event content
|
||||
*/
|
||||
protected void setEventContent(final byte[] eventData) {
|
||||
eventContent = new byte[eventData.length];
|
||||
System.arraycopy(eventContent, 0, eventData, 0, eventData.length);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the length of number of bytes in a PCR for the event.
|
||||
* event log format.
|
||||
*
|
||||
* @return byte array holding the events content field
|
||||
*/
|
||||
protected byte[] getEventContent() {
|
||||
return eventContent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the Digest Length.
|
||||
* Also the number of bytes expected within each PCR.
|
||||
*
|
||||
* @param length number of bytes in a PCR for the event.
|
||||
*/
|
||||
public void setDigestLength(final int length) {
|
||||
digestLength = length;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the length of number of bytes in a PCR for the event.
|
||||
*
|
||||
* @return Byte Array containing the PFP defined event content
|
||||
*/
|
||||
public int getDigestLength() {
|
||||
return digestLength;
|
||||
}
|
||||
}
|
51
HIRS_Utils/src/main/java/hirs/tpm/eventlog/TpmPcrEvent1.java
Normal file
51
HIRS_Utils/src/main/java/hirs/tpm/eventlog/TpmPcrEvent1.java
Normal file
@ -0,0 +1,51 @@
|
||||
package hirs.tpm.eventlog;
|
||||
|
||||
import hirs.utils.HexUtils;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* Class to process a TCG_PCR_EVENT.
|
||||
* TCG_PCR_EVENT is used when the Event log uses the SHA1 Format as described in the
|
||||
* TCG Platform Firmware Profile specification.
|
||||
* typedef struct {
|
||||
* UINT32 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
|
||||
* UINT32 EventType; //See Log event types
|
||||
* BYTE digest[20]; //The SHA1 hash of the event data
|
||||
* UINT32 EventSize; //Size of the event data
|
||||
* UINT8 Event[1]; //
|
||||
* } TCG_PCR_EVENT; //The event data structure to be added
|
||||
*/
|
||||
public class TpmPcrEvent1 extends TpmPcrEvent {
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param is ByteArrayInputStream holding the TCG Log event
|
||||
* @throws IOException if an error occurs in parsing the event
|
||||
*/
|
||||
public TpmPcrEvent1(final ByteArrayInputStream is) throws IOException {
|
||||
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];
|
||||
is.read(eventDigest);
|
||||
setDigest(eventDigest);
|
||||
is.read(unit32Data);
|
||||
int eventSize = HexUtils.leReverseInt(unit32Data);
|
||||
byte[] eventContent = new byte[eventSize];
|
||||
is.read(eventContent);
|
||||
}
|
||||
}
|
||||
}
|
97
HIRS_Utils/src/main/java/hirs/tpm/eventlog/TpmPcrEvent2.java
Normal file
97
HIRS_Utils/src/main/java/hirs/tpm/eventlog/TpmPcrEvent2.java
Normal file
@ -0,0 +1,97 @@
|
||||
package hirs.tpm.eventlog;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import hirs.utils.HexUtils;
|
||||
|
||||
/**
|
||||
* Class to process a TCG_PCR_EVENT2 which is used
|
||||
* when the Event log uses the Crypto Agile (SHA256) format as described in the
|
||||
* TCG Platform Firmware Profile specification.
|
||||
* This class will only process SHA-256 digests.
|
||||
* typedef struct {
|
||||
* UINT32 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
|
||||
* UINT32 EventType; //See Log event types
|
||||
* TPML_DIGEST_VALUES digest; //The hash of the event data
|
||||
* UINT32 EventSize; //Size of the event data
|
||||
* BYTE Event[1]; //The event data
|
||||
* } TCG_PCR_EVENT2; //The event data structure to be added
|
||||
* typedef struct {
|
||||
* UINT32 count;
|
||||
* TPMT_HA digests[HASH_COUNT];
|
||||
* } TPML_DIGEST_VALUES;
|
||||
* typedef struct {
|
||||
* TPMI_ALG_HASH hashAlg;
|
||||
* TPMU_HA digest;
|
||||
* } TPMT_HA;
|
||||
* typedef union {
|
||||
* BYTE sha1[SHA1_DIGEST_SIZE];
|
||||
* BYTE sha256[SHA256_DIGEST_SIZE];
|
||||
* BYTE sha384[SHA384_DIGEST_SIZE];
|
||||
* BYTE sha512[SHA512_DIGEST_SIZE];
|
||||
* } TPMU_HA;
|
||||
* define SHA1_DIGEST_SIZE 20
|
||||
* define SHA256_DIGEST_SIZE 32
|
||||
* define SHA384_DIGEST_SIZE 48
|
||||
* define SHA512_DIGEST_SIZE 64
|
||||
* typedef TPM_ALG_ID TPMI_ALG_HASH;
|
||||
* typedef UINT16 TPM_ALG_ID;
|
||||
* 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)
|
||||
*/
|
||||
public class TpmPcrEvent2 extends TpmPcrEvent {
|
||||
/**
|
||||
* algorithms found.
|
||||
*/
|
||||
private int algCount = 0;
|
||||
|
||||
/**
|
||||
* list of digests.
|
||||
*/
|
||||
private ArrayList<TcgTpmtHa> hashlist = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param is ByteArrayInputStream holding the TCG Log event
|
||||
* @throws IOException if an error occurs in parsing the event
|
||||
*/
|
||||
public TpmPcrEvent2(final ByteArrayInputStream is) throws IOException {
|
||||
super(is);
|
||||
setDigestLength(SHA256_LENGTH);
|
||||
//TCG_PCR_EVENT2
|
||||
byte[] rawInt = new byte[INT_LENGTH];
|
||||
if (is.available() > MIN_SIZE) {
|
||||
is.read(rawInt);
|
||||
setPcrIndex(rawInt);
|
||||
is.read(rawInt);
|
||||
setEventType(rawInt);
|
||||
// TPML_DIGEST_VALUES
|
||||
is.read(rawInt);
|
||||
algCount = HexUtils.leReverseInt(rawInt);
|
||||
TcgTpmtHa hashAlg = null;
|
||||
// Process TPMT_HA,
|
||||
for (int i = 0; i < algCount; i++) {
|
||||
hashAlg = new TcgTpmtHa(is);
|
||||
hashlist.add(hashAlg);
|
||||
if (hashAlg.getHashName().compareToIgnoreCase("TPM_ALG_SHA256") == 0) {
|
||||
setDigest(hashAlg.getDigest());
|
||||
}
|
||||
}
|
||||
is.read(rawInt);
|
||||
int eventSize = HexUtils.leReverseInt(rawInt);
|
||||
byte[] eventContent = new byte[eventSize];
|
||||
is.read(eventContent);
|
||||
setEventContent(eventContent);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,6 @@
|
||||
/**
|
||||
* Non-persistant classes related to TGC Event Logs.
|
||||
*/
|
||||
|
||||
package hirs.tpm.eventlog;
|
||||
|
@ -1,5 +1,7 @@
|
||||
package hirs.utils;
|
||||
|
||||
import java.math.BigInteger;
|
||||
|
||||
/**
|
||||
* Utilities for working with hex strings and byte arrays.
|
||||
*/
|
||||
@ -40,7 +42,7 @@ public final class HexUtils {
|
||||
* @return hex string representation of array
|
||||
*/
|
||||
public static String byteArrayToHexString(final byte[] b) {
|
||||
StringBuffer sb = new StringBuffer();
|
||||
StringBuilder sb = new StringBuilder();
|
||||
String returnStr = "";
|
||||
for (int i = 0; i < b.length; i++) {
|
||||
String singleByte = Integer.toHexString(b[i] & FF_BYTE);
|
||||
@ -74,4 +76,38 @@ public final class HexUtils {
|
||||
System.arraycopy(b, start, copy, 0, end - start + 1);
|
||||
return copy;
|
||||
}
|
||||
|
||||
/**
|
||||
* Takes in a byte array and reverses the order.
|
||||
* @param in byte array to reverse
|
||||
* @return reversed byte array
|
||||
*/
|
||||
public static byte[] leReverseByte(final byte[] in) {
|
||||
byte[] finished = new byte[in.length];
|
||||
for (int i = 0; i < finished.length; i++) {
|
||||
finished[i] = in[(in.length - 1) - i];
|
||||
}
|
||||
return finished;
|
||||
}
|
||||
|
||||
/**
|
||||
* Takes in a byte array and reverses the order then converts to an int.
|
||||
* @param in byte array to reverse
|
||||
* @return integer that represents the reversed byte array
|
||||
*/
|
||||
public static int leReverseInt(final byte[] in) {
|
||||
byte[] finished = leReverseByte(in);
|
||||
return new BigInteger(finished).intValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* Takes in a byte array of 4 bytes and returns a long.
|
||||
* @param bytes byte array to convert
|
||||
* @return long representation of the bytes
|
||||
*/
|
||||
public static long bytesToLong(final byte[] bytes) {
|
||||
BigInteger lValue = new BigInteger(bytes);
|
||||
|
||||
return lValue.abs().longValue();
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,175 @@
|
||||
package hirs.tpm.eventlog;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.Arrays;
|
||||
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.testng.Assert;
|
||||
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;
|
||||
|
||||
/**
|
||||
* Class for testing TCG Event Log processing.
|
||||
*/
|
||||
public class TCGEventLogProcessorTest extends SpringPersistenceTest {
|
||||
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";
|
||||
private static final Logger LOGGER
|
||||
= LogManager.getLogger(TCGEventLogProcessorTest.class);
|
||||
|
||||
/**
|
||||
* Initializes a <code>SessionFactory</code>. The factory is used for an in-memory database that
|
||||
* is used for testing.
|
||||
*/
|
||||
@BeforeClass
|
||||
public static final void setup() {
|
||||
LOGGER.debug("retrieving session factory");
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Closes the <code>SessionFactory</code> from setup.
|
||||
*/
|
||||
@AfterClass
|
||||
public static final void tearDown() {
|
||||
LOGGER.debug("closing session factory");
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets the test state to a known good state. This currently only resets the database by
|
||||
* removing all <code>Baseline</code> objects.
|
||||
*/
|
||||
// @AfterMethod
|
||||
public final void resetTestState() {
|
||||
LOGGER.debug("reset test state");
|
||||
LOGGER.debug("deleting all baselines");
|
||||
Session session = sessionFactory.getCurrentSession();
|
||||
session.beginTransaction();
|
||||
final List<?> baselines = session.createCriteria(Baseline.class).list();
|
||||
for (Object o : baselines) {
|
||||
LOGGER.debug("deleting baseline: {}", o);
|
||||
session.delete(o);
|
||||
}
|
||||
LOGGER.debug("all baselines removed");
|
||||
session.getTransaction().commit();
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the processing of a cryto agile event log.
|
||||
* @throws IOException when processing the test fails
|
||||
*/
|
||||
@Test
|
||||
public final void testCryptoAgileTCGEventLog() throws IOException {
|
||||
LOGGER.debug("Testing the parsing of a Crypto Agile formatted TCG Event Log");
|
||||
InputStream log, pcrs;
|
||||
boolean testPass = true;
|
||||
log = this.getClass().getResourceAsStream(DEFAULT_EVENT_LOG);
|
||||
byte[] rawLogBytes = IOUtils.toByteArray(log);
|
||||
TCGEventLogProcessor tlp = new TCGEventLogProcessor(rawLogBytes);
|
||||
String[] pcrFromLog = tlp.getExpectedPCRValues();
|
||||
pcrs = this.getClass().getResourceAsStream(DEFAULT_EXPECTED_PCRS);
|
||||
Object[] pcrObj = IOUtils.readLines(pcrs).toArray();
|
||||
String[] pcrTxt = Arrays.copyOf(pcrObj, pcrObj.length, String[].class);
|
||||
// Test 1 get all PCRs
|
||||
for (int i = 0; i < 24; i++) {
|
||||
if (pcrFromLog[i].compareToIgnoreCase(pcrTxt[i]) != 0) {
|
||||
testPass = false;
|
||||
LOGGER.error("\ntestTCGEventLogProcessorParser error with PCR " + i);
|
||||
}
|
||||
}
|
||||
Assert.assertTrue(testPass);
|
||||
// Test 2 get an individual PCR
|
||||
String pcr3 = tlp.getExpectedPCRValue(3);
|
||||
Assert.assertEquals(pcr3, pcrFromLog[3]);
|
||||
LOGGER.debug("OK. Parsing of a Crypto Agile Format Success");
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the processing of a SHA1 formatted Event log.
|
||||
* @throws IOException when processing the test fails
|
||||
*/
|
||||
@Test
|
||||
public final void testSHA1TCGEventLog() throws IOException {
|
||||
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);
|
||||
String[] pcrFromLog = tlp.getExpectedPCRValues();
|
||||
pcrs = this.getClass().getResourceAsStream(SHA1_EXPECTED_PCRS);
|
||||
Object[] pcrObj = IOUtils.readLines(pcrs).toArray();
|
||||
String[] pcrTxt = Arrays.copyOf(pcrObj, pcrObj.length, String[].class);
|
||||
// Test 1 get all PCRs
|
||||
for (int i = 0; i < 24; i++) {
|
||||
if (pcrFromLog[i].compareToIgnoreCase(pcrTxt[i]) != 0) {
|
||||
testPass = false;
|
||||
LOGGER.error("\ntestTCGEventLogProcessorParser error with PCR " + i);
|
||||
}
|
||||
}
|
||||
Assert.assertTrue(testPass);
|
||||
// Test 2 get an individual PCR
|
||||
String pcr0 = tlp.getExpectedPCRValue(0);
|
||||
Assert.assertEquals(pcr0, pcrFromLog[0]);
|
||||
LOGGER.debug("OK. Parsing of a SHA1 formatted TCG Event Log Success");
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests TPM Baseline creation from a EventLog.
|
||||
* @throws IOException when processing the test fails
|
||||
*/
|
||||
@Test
|
||||
public final void testTPMBaselineCreate() throws IOException {
|
||||
LOGGER.debug("Create and save TPM baseline from TCG Event Log test started");
|
||||
InputStream log;
|
||||
boolean testPass = true;
|
||||
log = this.getClass().getResourceAsStream(DEFAULT_EVENT_LOG);
|
||||
byte[] rawLogBytes = IOUtils.toByteArray(log);
|
||||
TCGEventLogProcessor tlp = new TCGEventLogProcessor(rawLogBytes);
|
||||
String[] pcrFromLog = tlp.getExpectedPCRValues();
|
||||
// save it to the test db
|
||||
LOGGER.debug("Creating and saving a TPM baseline from TCG Event Log");
|
||||
Session session = sessionFactory.getCurrentSession();
|
||||
session.beginTransaction();
|
||||
final TpmWhiteListBaseline b = tlp.createTPMBaseline("TcgEventLogTestBaseline");
|
||||
session.save(b);
|
||||
session.getTransaction().commit();
|
||||
// Check that the TPM Baseline contains he correct info
|
||||
for (int i = 0; i < 24; i++) {
|
||||
Set<Digest> records = b.getPCRHashes(i);
|
||||
for (Digest digest:records) {
|
||||
String pcrValue = HexUtils.byteArrayToHexString(digest.getDigest());
|
||||
if (pcrFromLog[i].compareToIgnoreCase(pcrValue) != 0) {
|
||||
testPass = false;
|
||||
LOGGER.error("\testTPMBaselineCreate error with PCR " + i);
|
||||
}
|
||||
}
|
||||
}
|
||||
Assert.assertTrue(testPass);
|
||||
LOGGER.debug("OK. Create and save TPM baseline from TCG Event Log was a success");
|
||||
}
|
||||
}
|
@ -0,0 +1,5 @@
|
||||
/**
|
||||
* Test classes for the hirs.tpm package.
|
||||
*/
|
||||
|
||||
package hirs.tpm.eventlog;
|
BIN
HIRS_Utils/src/test/resources/tcgeventlog/TpmLog.bin
Normal file
BIN
HIRS_Utils/src/test/resources/tcgeventlog/TpmLog.bin
Normal file
Binary file not shown.
@ -0,0 +1,24 @@
|
||||
5ef6c69a589a96b5ade6a09e960eb341e6f68a8239df66be34e5e991ddde97a8
|
||||
0f16d93fe0cbe7114fd9fefeb1d98a0802b184b6077f05275269aa90ebb8a993
|
||||
966eb0b055e5b656f81c08ed1b2107cdea5740f321382d07a0eade7d014addee
|
||||
3d458cfe55cc03ea1f443f1562beec8df51c75e14a9fcf9a7234a13f198e7969
|
||||
c919e77702cb066016b575c008659ba7d758b0b4c3f9df29658e1770699823d1
|
||||
45f6dd68feb493ec2f371f2fbd2f904181a20e9491102304f239745f6fd1eaf6
|
||||
3d458cfe55cc03ea1f443f1562beec8df51c75e14a9fcf9a7234a13f198e7969
|
||||
65caf8dd1e0ea7a6347b635d2b379c93b9a1351edc2afc3ecda700e534eb3068
|
||||
0000000000000000000000000000000000000000000000000000000000000000
|
||||
0000000000000000000000000000000000000000000000000000000000000000
|
||||
0000000000000000000000000000000000000000000000000000000000000000
|
||||
0000000000000000000000000000000000000000000000000000000000000000
|
||||
0000000000000000000000000000000000000000000000000000000000000000
|
||||
0000000000000000000000000000000000000000000000000000000000000000
|
||||
0000000000000000000000000000000000000000000000000000000000000000
|
||||
0000000000000000000000000000000000000000000000000000000000000000
|
||||
0000000000000000000000000000000000000000000000000000000000000000
|
||||
0000000000000000000000000000000000000000000000000000000000000000
|
||||
0000000000000000000000000000000000000000000000000000000000000000
|
||||
0000000000000000000000000000000000000000000000000000000000000000
|
||||
0000000000000000000000000000000000000000000000000000000000000000
|
||||
0000000000000000000000000000000000000000000000000000000000000000
|
||||
0000000000000000000000000000000000000000000000000000000000000000
|
||||
0000000000000000000000000000000000000000000000000000000000000000
|
BIN
HIRS_Utils/src/test/resources/tcgeventlog/TpmLogSHA1.bin
Normal file
BIN
HIRS_Utils/src/test/resources/tcgeventlog/TpmLogSHA1.bin
Normal file
Binary file not shown.
@ -0,0 +1,24 @@
|
||||
1f1e9bf7dea0be1c37c999c4233b0164ed577607
|
||||
46f041010f19e5e74aa33e04467c59759af3fca4
|
||||
b2a83b0ebf2f8374299a5b2bdfc31ea955ad7236
|
||||
b2a83b0ebf2f8374299a5b2bdfc31ea955ad7236
|
||||
f36f2acdb5134d2560e7784002f606573bac99d5
|
||||
ed6db334e4e0f3811c18b9e79601b0c16d5a5b2b
|
||||
b2a83b0ebf2f8374299a5b2bdfc31ea955ad7236
|
||||
54f675801f2f654bf53fc61c36837198fddd7a85
|
||||
0000000000000000000000000000000000000000
|
||||
0000000000000000000000000000000000000000
|
||||
0000000000000000000000000000000000000000
|
||||
0000000000000000000000000000000000000000
|
||||
0000000000000000000000000000000000000000
|
||||
0000000000000000000000000000000000000000
|
||||
0000000000000000000000000000000000000000
|
||||
0000000000000000000000000000000000000000
|
||||
0000000000000000000000000000000000000000
|
||||
0000000000000000000000000000000000000000
|
||||
0000000000000000000000000000000000000000
|
||||
0000000000000000000000000000000000000000
|
||||
0000000000000000000000000000000000000000
|
||||
0000000000000000000000000000000000000000
|
||||
0000000000000000000000000000000000000000
|
||||
0000000000000000000000000000000000000000
|
Loading…
x
Reference in New Issue
Block a user