mirror of
https://github.com/nsacyber/HIRS.git
synced 2024-12-18 20:47:58 +00:00
Updates to allow for TPM 2.0 quote.
This commit is contained in:
parent
aeebd068f5
commit
efbd22812d
@ -9,6 +9,7 @@ CERTS_DIR="/etc/hirs/provisioner/certs/"
|
||||
HIRS_SITE_CONFIG="/etc/hirs/hirs-site.config"
|
||||
HIRS_PROVISIONER_CONFIG="/etc/hirs/provisioner/hirs-provisioner-config.sh"
|
||||
HIRS_PROVISIONER_SCRIPT="/usr/share/hirs/provisioner/bin/HIRS_Provisioner"
|
||||
HIRS_PROVISIONER_2_0_SCRIPT="/usr/local/bin/hirs-provisioner-tpm2"
|
||||
HIRS_PROVISIONER_PROPERTIES="/etc/hirs/provisioner/provisioner.properties"
|
||||
|
||||
if [ "$EUID" != "0" ]; then
|
||||
@ -105,10 +106,16 @@ function CheckProvisionPrereqsAndDoProvisioning {
|
||||
|
||||
function Provision {
|
||||
# Provisioner will only retain one {uuid}.cer credential; remove any existing *.cer files.
|
||||
echo "----> Removing old provisioner scripts, if any"
|
||||
rm -f $CERTS_DIR/*.cer
|
||||
echo "----> Removing old attestation credentials, if any"
|
||||
rm -f $CERTS_DIR/*.cer /etc/hirs/ak.cer
|
||||
echo "----> Provisioning TPM"
|
||||
$HIRS_PROVISIONER_SCRIPT $CLIENT_HOSTNAME || { echo "----> Failed to provision TPM"; exit 1; }
|
||||
|
||||
if [ -f $HIRS_PROVISIONER_2_0_SCRIPT ]
|
||||
then
|
||||
$HIRS_PROVISIONER_2_0_SCRIPT provision || { echo "----> Failed to provision TPM 2.0"; exit 1; }
|
||||
else
|
||||
$HIRS_PROVISIONER_SCRIPT $CLIENT_HOSTNAME || { echo "----> Failed to provision TPM"; exit 1; }
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
|
@ -140,11 +140,11 @@ list(APPEND REQUIRED_LIBS ${PROTOBUF_LIBRARY})
|
||||
# Define the TPM 2.0 Provisioner Library
|
||||
add_subdirectory(src)
|
||||
|
||||
# Set Project Header/Source files
|
||||
set(EXECUTABLE_SOURCE_FILES src/TPM2_Provisioner.cpp)
|
||||
|
||||
# Create project executable
|
||||
add_executable(${PROJECT_NAME} ${EXECUTABLE_SOURCE_FILES} ${PROJECT_CONFIG_FILES})
|
||||
add_executable(${PROJECT_NAME} src/TPM2_Provisioner.cpp ${PROJECT_CONFIG_FILES})
|
||||
|
||||
# In TPM 2.0 land, there is currently not a way to fetch the TPM version info
|
||||
add_executable(tpm_version src/tpm_version.cpp)
|
||||
|
||||
# Link necessary libraries
|
||||
target_link_libraries(${PROJECT_NAME} TPM2_PROVISIONER_LIBRARY)
|
||||
@ -159,13 +159,25 @@ if(CMAKE_THREAD_LIBS_INIT)
|
||||
endif()
|
||||
|
||||
# Set commands for installation of project on target system (i.e. "make install")
|
||||
install(TARGETS ${PROJECT_NAME}
|
||||
install(TARGETS ${PROJECT_NAME} tpm_version
|
||||
DESTINATION "bin")
|
||||
install(FILES config/log4cplus_config.ini DESTINATION /etc/hirs/TPM2_Provisioner)
|
||||
install(FILES scripts/tpm_aca_provision DESTINATION /usr/local/bin PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE)
|
||||
install(DIRECTORY DESTINATION ${/var/log/hirs/provisioner}
|
||||
DIRECTORY_PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ
|
||||
GROUP_EXECUTE WORLD_READ WORLD_EXECUTE)
|
||||
|
||||
install(DIRECTORY DESTINATION ${/etc/hirs/provisioner}
|
||||
DIRECTORY_PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ
|
||||
GROUP_EXECUTE WORLD_READ WORLD_EXECUTE)
|
||||
install(FILES ../HIRS_Provisioner/src/main/resources/defaults.properties DESTINATION /etc/hirs/provisioner RENAME provisioner.properties)
|
||||
install(FILES ../HIRS_Provisioner/hirs-provisioner-config.sh DESTINATION /etc/hirs/provisioner
|
||||
PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ
|
||||
GROUP_EXECUTE WORLD_READ WORLD_EXECUTE)
|
||||
install(FILES ../HIRS_Provisioner/scripts/install/hirs-provisioner.sh DESTINATION /etc/hirs/provisioner
|
||||
PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ
|
||||
GROUP_EXECUTE WORLD_READ WORLD_EXECUTE)
|
||||
|
||||
execute_process(COMMAND cp ../HIRS_Utils/src/main/resources/logging.properties ./config/
|
||||
RESULT_VARIABLE result
|
||||
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR})
|
||||
|
@ -1,8 +1,10 @@
|
||||
HIRS_SITE_CONFIG="/etc/hirs/hirs-site.config"
|
||||
|
||||
mkdir -p /var/log/hirs/provisioner
|
||||
mkdir -p /etc/hirs/provisioner/certs
|
||||
ln -s -f /usr/local/bin/hirs-provisioner-tpm2 /usr/sbin/hirs-provisioner-tpm2
|
||||
ln -s -f /usr/local/bin/tpm_aca_provision /usr/sbin/tpm_aca_provision
|
||||
ln -s -f /usr/local/bin/tpm_version /usr/sbin/tpm_version
|
||||
|
||||
if [ ! -f $HIRS_SITE_CONFIG ]; then
|
||||
# Create template site config if it does not exist
|
||||
@ -29,3 +31,4 @@ DEFAULT_SITE_CONFIG_FILE
|
||||
echo "$HIRS_SITE_CONFIG not found - a template has been created"
|
||||
echo "Set your site configuration manually in $HIRS_SITE_CONFIG, then run 'hirs-provisioner-tpm2 provision' to provision this system"
|
||||
fi
|
||||
ln -s -f /etc/hirs/provisioner/hirs-provisioner.sh /usr/sbin/hirs-provisioner
|
||||
|
@ -8,8 +8,10 @@ fi
|
||||
HIRS_SITE_CONFIG="/etc/hirs/hirs-site.config"
|
||||
|
||||
mkdir -p /var/log/hirs/provisioner
|
||||
mkdir -p /etc/hirs/provisioner/certs
|
||||
ln -s -f /usr/local/bin/hirs-provisioner-tpm2 /usr/sbin/hirs-provisioner-tpm2
|
||||
ln -s -f /usr/local/bin/tpm_aca_provision /usr/sbin/tpm_aca_provision
|
||||
ln -s -f /usr/local/bin/tpm_version /usr/sbin/tpm_version
|
||||
|
||||
if [ ! -f $HIRS_SITE_CONFIG ]; then
|
||||
# Create template site config if it does not exist
|
||||
@ -36,3 +38,4 @@ DEFAULT_SITE_CONFIG_FILE
|
||||
echo "$HIRS_SITE_CONFIG not found - a template has been created"
|
||||
echo "Set your site configuration manually in $HIRS_SITE_CONFIG, then run 'hirs-provisioner-tpm2 provision' to provision this system"
|
||||
fi
|
||||
ln -s -f /etc/hirs/provisioner/hirs-provisioner.sh /usr/sbin/hirs-provisioner
|
||||
|
11
HIRS_ProvisionerTPM2/src/tpm_version.cpp
Normal file
11
HIRS_ProvisionerTPM2/src/tpm_version.cpp
Normal file
@ -0,0 +1,11 @@
|
||||
#include <iostream>
|
||||
|
||||
using std::cout;
|
||||
using std::endl;
|
||||
|
||||
int main(void) {
|
||||
cout << "Chip Version: 2.0.0.0" << endl;
|
||||
cout << "TPM Vendor ID: UNKN" << endl;
|
||||
return 0;
|
||||
}
|
||||
|
@ -61,9 +61,6 @@ public final class TPMMeasurementRecord extends ExaminableRecord {
|
||||
LOGGER.error("null hash value");
|
||||
throw new NullPointerException("hash");
|
||||
}
|
||||
if (hash.getAlgorithm() != DigestAlgorithm.SHA1) {
|
||||
throw new IllegalArgumentException("hash algorithm is not SHA-1");
|
||||
}
|
||||
|
||||
this.pcrId = pcrId;
|
||||
this.hash = hash;
|
||||
|
@ -1,5 +1,7 @@
|
||||
package hirs.data.persist.tpm;
|
||||
|
||||
import hirs.data.persist.Digest;
|
||||
import hirs.data.persist.DigestAlgorithm;
|
||||
import hirs.data.persist.TPMMeasurementRecord;
|
||||
|
||||
import javax.persistence.AttributeOverride;
|
||||
@ -21,6 +23,8 @@ import java.nio.ByteBuffer;
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.util.Arrays;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Java class for PcrInfoShort complex type, which was modified from code
|
||||
@ -200,16 +204,31 @@ public class PcrInfoShort {
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the digest of the PCR values the same way a TPM computes the digest contained in
|
||||
* the quote. Useful for TPM appraisal and for ensuring the digest of the collected PCR values
|
||||
* match the digest in the quote.
|
||||
* Calculates the SHA-1 or SHA-256 digest of the PCR values the same way a TPM computes the
|
||||
* digest contained in the quote. Useful for TPM appraisal and for ensuring the digest of the
|
||||
* collected PCR values match the digest in the quote.
|
||||
*
|
||||
* @return byte array containing the digest
|
||||
* @throws NoSuchAlgorithmException
|
||||
* if MessageDigest doesn't recognize "SHA-1"
|
||||
* if MessageDigest doesn't recognize "SHA-1" or "SHA-256"
|
||||
*/
|
||||
public final byte[] getCalculatedDigest() throws NoSuchAlgorithmException {
|
||||
MessageDigest messageDigest = MessageDigest.getInstance("SHA-1");
|
||||
if (this.isTpm1()) {
|
||||
return getCalculatedDigestTpmV1p2(MessageDigest.getInstance("SHA-1"));
|
||||
} else {
|
||||
return getCalculatedDigestTpmV2p0(MessageDigest.getInstance("SHA-256"));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the SHA-1 digest of the PCR values the same way a TPM computes the digest
|
||||
* contained in the quote. Useful for TPM appraisal and for ensuring the digest of the
|
||||
* collected PCR values match the digest in the quote.
|
||||
*
|
||||
* @param messageDigest message digest algorithm to use
|
||||
* @return byte array containing the digest
|
||||
*/
|
||||
private byte[] getCalculatedDigestTpmV1p2(final MessageDigest messageDigest) {
|
||||
byte[] computedDigest;
|
||||
|
||||
final int sizeOfInt = 4;
|
||||
@ -235,6 +254,32 @@ public class PcrInfoShort {
|
||||
return computedDigest;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the digest of the PCR values the same way a TPM computes the digest contained in
|
||||
* the quote. Useful for TPM appraisal and for ensuring the digest of the collected PCR values
|
||||
* match the digest in the quote.
|
||||
*
|
||||
* @param messageDigest message digest algorithm to use
|
||||
* @return byte array containing the digest
|
||||
*/
|
||||
private byte[] getCalculatedDigestTpmV2p0(final MessageDigest messageDigest) {
|
||||
int sizeOfByteBuffer = pcrComposite.getValueSize();
|
||||
ByteBuffer byteBuffer = ByteBuffer.allocate(sizeOfByteBuffer);
|
||||
LOGGER.debug("Size of the buffer allocated to hash: {}", sizeOfByteBuffer);
|
||||
Iterator iter = pcrComposite.getPcrValueList().iterator();
|
||||
|
||||
while (iter.hasNext()) {
|
||||
TPMMeasurementRecord record = (TPMMeasurementRecord) iter.next();
|
||||
byteBuffer.put(record.getHash().getDigest());
|
||||
}
|
||||
|
||||
LOGGER.debug("PCR composite buffer to be hashed: {}",
|
||||
Hex.encodeHexString(byteBuffer.array()));
|
||||
byte[] computedDigest = messageDigest.digest(byteBuffer.array());
|
||||
LOGGER.debug("Calculated digest: {}", Hex.encodeHexString(computedDigest));
|
||||
return computedDigest;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the value of PcrInfoShort flattened into a byte array. The array contains the value
|
||||
* of PCR selection, the locality at release, and the composite hash.
|
||||
@ -250,4 +295,22 @@ public class PcrInfoShort {
|
||||
|
||||
return byteBuffer.array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines whether the TPM used to generate this pcr info is version 1.2 or not.
|
||||
*
|
||||
* @return whether the TPM used to generate this pcr info is version 1.2 or not
|
||||
*/
|
||||
public boolean isTpm1() {
|
||||
// need to get an individual PCR and measure length to determine SHA1 v SHA 256
|
||||
List<TPMMeasurementRecord> pcrs = this.getPcrComposite().getPcrValueList();
|
||||
if (pcrs.size() == 0) {
|
||||
// it's the case of an empty pcrmask, so it doesn't matter
|
||||
return false;
|
||||
}
|
||||
|
||||
Digest hash = pcrs.get(0).getHash();
|
||||
// check if the hash algorithm is SHA 1, if so it's TPM 1.2, if not it's TPM 2.0
|
||||
return hash.getAlgorithm() == DigestAlgorithm.SHA1;
|
||||
}
|
||||
}
|
||||
|
@ -52,11 +52,15 @@ import java.util.Arrays;
|
||||
name = "QuoteSignature",
|
||||
namespace = "http://www.trustedcomputinggroup.org/XML/SCHEMA/"
|
||||
+ "Integrity_Report_v1_0#",
|
||||
propOrder = {"signatureValue" })
|
||||
propOrder = {"rawQuote", "signatureValue" })
|
||||
@Embeddable
|
||||
public class QuoteSignature {
|
||||
private static final int SIGNATURE_LENGTH = 10000;
|
||||
|
||||
@XmlElement(name = "RawQuote", required = false)
|
||||
@Column(length = SIGNATURE_LENGTH)
|
||||
private final byte[] rawQuote;
|
||||
|
||||
@XmlElement(name = "SignatureValue", required = true)
|
||||
@Column(length = SIGNATURE_LENGTH)
|
||||
private final byte[] signatureValue;
|
||||
@ -65,6 +69,7 @@ public class QuoteSignature {
|
||||
* Default constructor necessary for marshalling/unmarshalling xml.
|
||||
*/
|
||||
protected QuoteSignature() {
|
||||
this.rawQuote = new byte[0];
|
||||
this.signatureValue = new byte[0];
|
||||
}
|
||||
|
||||
@ -76,6 +81,23 @@ public class QuoteSignature {
|
||||
* SignatureValue that contains the Quote2 signature, may be null
|
||||
*/
|
||||
public QuoteSignature(final byte[] signatureValue) {
|
||||
this(signatureValue, null);
|
||||
}
|
||||
/**
|
||||
* Constructor used to create a QuoteSignature. The signature value may be
|
||||
* null.
|
||||
*
|
||||
* @param signatureValue
|
||||
* SignatureValue that contains the Quote2 signature, may be null
|
||||
* @param rawQuote
|
||||
* Value that was signed, may be null
|
||||
*/
|
||||
public QuoteSignature(final byte[] signatureValue, final byte[] rawQuote) {
|
||||
if (rawQuote == null) {
|
||||
this.rawQuote = null;
|
||||
} else {
|
||||
this.rawQuote = rawQuote.clone();
|
||||
}
|
||||
if (signatureValue == null) {
|
||||
this.signatureValue = null;
|
||||
} else {
|
||||
@ -90,11 +112,24 @@ public class QuoteSignature {
|
||||
*
|
||||
*/
|
||||
public final byte[] getSignatureValue() {
|
||||
if (signatureValue == null) {
|
||||
return null;
|
||||
} else {
|
||||
if (signatureValue != null) {
|
||||
return signatureValue.clone();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the rawQuote property.
|
||||
*
|
||||
* @return possible object is a byte array containing the raw quote value, may return null
|
||||
*
|
||||
*/
|
||||
public byte[] getRawQuote() {
|
||||
if (rawQuote != null) {
|
||||
return rawQuote.clone();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
Loading…
Reference in New Issue
Block a user