mirror of
https://github.com/nsacyber/HIRS.git
synced 2025-02-20 17:52:47 +00:00
add support for EvCompactHash EvEfiSpecIdEvent and EvNoAction events
This commit is contained in:
parent
faa77be822
commit
94cf172ce8
@ -0,0 +1,52 @@
|
||||
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 {
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
@ -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<String> algList = new ArrayList<String>();
|
||||
|
||||
/**
|
||||
* 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<String> 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;
|
||||
}
|
||||
}
|
@ -0,0 +1,81 @@
|
||||
package hirs.tpm.eventlog.events;
|
||||
|
||||
import java.io.UnsupportedEncodingException;
|
||||
|
||||
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_16];
|
||||
System.arraycopy(eventData, 0, signatureBytes, 0, UefiConstants.SIZE_16);
|
||||
signature = new String(signatureBytes, "UFT-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;
|
||||
}
|
||||
}
|
@ -0,0 +1,6 @@
|
||||
/**
|
||||
* Non-persistant classes related to TGC Event Logs.
|
||||
*/
|
||||
|
||||
package hirs.tpm.eventlog.events;
|
||||
|
@ -19,10 +19,18 @@ public final class UefiConstants {
|
||||
public static final int SIZE_5 = 5;
|
||||
/** 8 byte size. */
|
||||
public static final int SIZE_8 = 8;
|
||||
/** 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 = 20;
|
||||
/** 22 byte size. */
|
||||
public static final int SIZE_22 = 20;
|
||||
/** 23 byte size. */
|
||||
public static final int SIZE_23 = 20;
|
||||
/** 28 byte size. */
|
||||
public static final int SIZE_28 = 28;
|
||||
/** 32 byte size. */
|
||||
@ -47,6 +55,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. */
|
||||
|
Loading…
x
Reference in New Issue
Block a user