Fixed calculate quote info function -> initialize PCR bit mask array with zeroes
Return TPM Quote Info only, hash of it is calculated in IMV Process Renamed digest with quote info
This commit is contained in:
committed by
Andreas Steffen
parent
baee8292ad
commit
72684a710b
@@ -30,6 +30,7 @@
|
|||||||
#include <tcg/tcg_pts_attr_unix_file_meta.h>
|
#include <tcg/tcg_pts_attr_unix_file_meta.h>
|
||||||
|
|
||||||
#include <debug.h>
|
#include <debug.h>
|
||||||
|
#include <crypto/hashers/hasher.h>
|
||||||
|
|
||||||
bool imv_attestation_process(pa_tnc_attr_t *attr, linked_list_t *attr_list,
|
bool imv_attestation_process(pa_tnc_attr_t *attr, linked_list_t *attr_list,
|
||||||
imv_attestation_state_t *attestation_state,
|
imv_attestation_state_t *attestation_state,
|
||||||
@@ -294,32 +295,46 @@ bool imv_attestation_process(pa_tnc_attr_t *attr, linked_list_t *attr_list,
|
|||||||
}
|
}
|
||||||
if (flags == PTS_SIMPLE_EVID_FINAL_FLAG_TPM_QUOTE_INFO)
|
if (flags == PTS_SIMPLE_EVID_FINAL_FLAG_TPM_QUOTE_INFO)
|
||||||
{
|
{
|
||||||
chunk_t digest;
|
chunk_t quote_info, quote_digest;
|
||||||
|
hasher_t *hasher;
|
||||||
pcr_comp = attr_cast->get_pcr_comp(attr_cast);
|
pcr_comp = attr_cast->get_pcr_comp(attr_cast);
|
||||||
tpm_quote_sign = attr_cast->get_tpm_quote_sign(attr_cast);
|
tpm_quote_sign = attr_cast->get_tpm_quote_sign(attr_cast);
|
||||||
|
|
||||||
if (!pts->get_quote_digest(pts, &digest))
|
if (!pts->get_quote_info(pts, "e_info))
|
||||||
{
|
{
|
||||||
DBG1(DBG_IMV, "unable to contruct TPM Quote Digest");
|
DBG1(DBG_IMV, "unable to contruct TPM Quote Info");
|
||||||
free(digest.ptr);
|
free(quote_info.ptr);
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
if (!pts->verify_quote_signature(pts, digest, tpm_quote_sign))
|
|
||||||
{
|
|
||||||
free(digest.ptr);
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
DBG2(DBG_IMV, "signature verification succeeded for TPM Quote Info");
|
/* SHA1(TPM Quote Info) expected from IMC */
|
||||||
|
hasher = lib->crypto->create_hasher(lib->crypto, HASH_SHA1);
|
||||||
|
hasher->allocate_hash(hasher, quote_info, "e_digest);
|
||||||
|
hasher->destroy(hasher);
|
||||||
|
|
||||||
if (!chunk_equals(digest, pcr_comp))
|
if (!chunk_equals(pcr_comp, chunk_empty)
|
||||||
|
&& strncmp(quote_info.ptr, pcr_comp.ptr,
|
||||||
|
quote_info.len - ASSESSMENT_SECRET_LEN) != 0)
|
||||||
{
|
{
|
||||||
DBG1(DBG_IMV, "calculated TPM Quote Info differs from received");
|
DBG1(DBG_IMV, "calculated TPM Quote Info differs from received");
|
||||||
DBG1(DBG_IMV, "calculated: %B", &digest);
|
DBG3(DBG_IMV, "calculated: %B", "e_info);
|
||||||
DBG1(DBG_IMV, "received: %B", &pcr_comp);
|
DBG3(DBG_IMV, "received: %B", &pcr_comp);
|
||||||
|
free(quote_digest.ptr);
|
||||||
|
free(quote_info.ptr);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
free(digest.ptr);
|
DBG2(DBG_IMV, "received TPM Quote Info matches with calculated");
|
||||||
|
|
||||||
|
if (!chunk_equals(tpm_quote_sign, chunk_empty) &&
|
||||||
|
!pts->verify_quote_signature(pts, quote_digest, tpm_quote_sign))
|
||||||
|
{
|
||||||
|
free(quote_digest.ptr);
|
||||||
|
free(quote_info.ptr);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
DBG2(DBG_IMV, "signature verification succeeded for TPM Quote Info");
|
||||||
|
free(quote_digest.ptr);
|
||||||
|
free(quote_info.ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (evid_signature_included)
|
if (evid_signature_included)
|
||||||
|
|||||||
+16
-42
@@ -904,28 +904,6 @@ METHOD(pts_t, quote_tpm, bool,
|
|||||||
goto err4;
|
goto err4;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Display quote info */
|
|
||||||
DBG3(DBG_PTS, "version:");
|
|
||||||
for(i = 0 ; i < 4 ; i++)
|
|
||||||
{
|
|
||||||
DBG3(DBG_PTS, "%02X ",valData.rgbData[i]);
|
|
||||||
}
|
|
||||||
DBG3(DBG_PTS, "fixed value:");
|
|
||||||
for(i = 4 ; i < 8 ; i++)
|
|
||||||
{
|
|
||||||
DBG3(DBG_PTS, "%c",valData.rgbData[i]);
|
|
||||||
}
|
|
||||||
DBG3(DBG_PTS, "pcr digest:");
|
|
||||||
for(i = 8 ; i < 28 ; i++)
|
|
||||||
{
|
|
||||||
DBG3(DBG_PTS, "%02X ",valData.rgbData[i]);
|
|
||||||
}
|
|
||||||
DBG3(DBG_PTS, "nonce:");
|
|
||||||
for(i = 28 ; i < valData.ulDataLength ; i++)
|
|
||||||
{
|
|
||||||
DBG3(DBG_PTS, "%02X ",valData.rgbData[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Set output chunks */
|
/* Set output chunks */
|
||||||
pcr_comp = chunk_alloc(valData.ulDataLength - ASSESSMENT_SECRET_LEN);
|
pcr_comp = chunk_alloc(valData.ulDataLength - ASSESSMENT_SECRET_LEN);
|
||||||
memcpy(pcr_comp.ptr, valData.rgbData,
|
memcpy(pcr_comp.ptr, valData.rgbData,
|
||||||
@@ -1090,7 +1068,7 @@ METHOD(pts_t, does_pcr_value_match, bool,
|
|||||||
e = entries->create_enumerator(entries);
|
e = entries->create_enumerator(entries);
|
||||||
while (e->enumerate(e, &pcr_entry))
|
while (e->enumerate(e, &pcr_entry))
|
||||||
{
|
{
|
||||||
if (chunk_equals(chunk_create(pcr_entry->pcr_value, PCR_LEN), pcr_after_value))
|
if (strncmp(pcr_entry->pcr_value, pcr_after_value.ptr, PCR_LEN) == 0)
|
||||||
{
|
{
|
||||||
DBG1(DBG_PTS, "PCR %d value matched with configured value",
|
DBG1(DBG_PTS, "PCR %d value matched with configured value",
|
||||||
pcr_entry->pcr_number);
|
pcr_entry->pcr_number);
|
||||||
@@ -1136,25 +1114,23 @@ METHOD(pts_t, does_pcr_value_match, bool,
|
|||||||
* 4 bytes 'Q' 'U' 'O' 'T'
|
* 4 bytes 'Q' 'U' 'O' 'T'
|
||||||
* 20 byte SHA1 of TCPA_PCR_COMPOSITE
|
* 20 byte SHA1 of TCPA_PCR_COMPOSITE
|
||||||
* 20 byte nonce
|
* 20 byte nonce
|
||||||
*
|
|
||||||
* 4. SHA1(TCPA_QUOTE_INFO) gives quoteDigest
|
|
||||||
*/
|
*/
|
||||||
static chunk_t calculate_quote_digest(private_pts_t *this, linked_list_t *pcr_entries)
|
static chunk_t calculate_quote_info(private_pts_t *this, linked_list_t *pcr_entries)
|
||||||
{
|
{
|
||||||
enumerator_t *e;
|
enumerator_t *e;
|
||||||
pcr_entry_t *pcr_entry;
|
pcr_entry_t *pcr_entry;
|
||||||
chunk_t digest, hash_digest, pcr_composite, hash_pcr_composite;
|
chunk_t quote_info, pcr_composite, hash_pcr_composite;
|
||||||
u_int32_t pcr_composite_len;
|
u_int32_t pcr_composite_len;
|
||||||
bio_writer_t *writer;
|
bio_writer_t *writer;
|
||||||
u_int8_t mask_bytes[MAX_NUM_PCR / 8], i;
|
u_int8_t mask_bytes[PCR_MASK_LEN] = {0,0,0}, i;
|
||||||
hasher_t *hasher;
|
hasher_t *hasher;
|
||||||
|
|
||||||
pcr_composite_len = 2 + (MAX_NUM_PCR / 8) + 4 +
|
pcr_composite_len = 2 + PCR_MASK_LEN + 4 +
|
||||||
pcr_entries->get_count(pcr_entries) * PCR_LEN;
|
pcr_entries->get_count(pcr_entries) * PCR_LEN;
|
||||||
|
|
||||||
writer = bio_writer_create(pcr_composite_len);
|
writer = bio_writer_create(pcr_composite_len);
|
||||||
/* Lenght of the bist mask field */
|
/* Lenght of the bist mask field */
|
||||||
writer->write_uint16(writer, (MAX_NUM_PCR / 8));
|
writer->write_uint16(writer, PCR_MASK_LEN);
|
||||||
/* Bit mask indicating selected PCRs */
|
/* Bit mask indicating selected PCRs */
|
||||||
e = pcr_entries->create_enumerator(pcr_entries);
|
e = pcr_entries->create_enumerator(pcr_entries);
|
||||||
while (e->enumerate(e, &pcr_entry))
|
while (e->enumerate(e, &pcr_entry))
|
||||||
@@ -1164,7 +1140,7 @@ static chunk_t calculate_quote_digest(private_pts_t *this, linked_list_t *pcr_en
|
|||||||
}
|
}
|
||||||
|
|
||||||
e->destroy(e);
|
e->destroy(e);
|
||||||
for (i = 0; i< (MAX_NUM_PCR / 8) ; i++)
|
for (i = 0; i< PCR_MASK_LEN ; i++)
|
||||||
{
|
{
|
||||||
writer->write_uint8(writer, mask_bytes[i]);
|
writer->write_uint8(writer, mask_bytes[i]);
|
||||||
}
|
}
|
||||||
@@ -1203,26 +1179,22 @@ static chunk_t calculate_quote_digest(private_pts_t *this, linked_list_t *pcr_en
|
|||||||
writer->write_data(writer, this->secret);
|
writer->write_data(writer, this->secret);
|
||||||
|
|
||||||
/* TPM Quote Info */
|
/* TPM Quote Info */
|
||||||
digest = chunk_clone(writer->get_buf(writer));
|
quote_info = chunk_clone(writer->get_buf(writer));
|
||||||
DBG3(DBG_PTS, "Calculated TPM Quote Digest: %B", &digest);
|
DBG3(DBG_PTS, "Calculated TPM Quote Info: %B", "e_info);
|
||||||
|
|
||||||
/* SHA1(TPM Quote Info) expected from IMC */
|
|
||||||
hasher->allocate_hash(hasher, digest, &hash_digest);
|
|
||||||
|
|
||||||
e->destroy(e);
|
e->destroy(e);
|
||||||
writer->destroy(writer);
|
writer->destroy(writer);
|
||||||
hasher->destroy(hasher);
|
hasher->destroy(hasher);
|
||||||
chunk_clear(&pcr_composite);
|
chunk_clear(&pcr_composite);
|
||||||
chunk_clear(&hash_pcr_composite);
|
chunk_clear(&hash_pcr_composite);
|
||||||
chunk_clear(&digest);
|
|
||||||
free(pcr_entry);
|
free(pcr_entry);
|
||||||
pcr_entries->destroy(pcr_entries);
|
pcr_entries->destroy(pcr_entries);
|
||||||
|
|
||||||
return hash_digest;
|
return quote_info;
|
||||||
}
|
}
|
||||||
|
|
||||||
METHOD(pts_t, get_quote_digest, bool,
|
METHOD(pts_t, get_quote_info, bool,
|
||||||
private_pts_t *this, chunk_t *digest)
|
private_pts_t *this, chunk_t *quote_info)
|
||||||
{
|
{
|
||||||
linked_list_t *entries;
|
linked_list_t *entries;
|
||||||
|
|
||||||
@@ -1232,13 +1204,14 @@ METHOD(pts_t, get_quote_digest, bool,
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
*digest = calculate_quote_digest(this, entries);
|
*quote_info = calculate_quote_info(this, entries);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
METHOD(pts_t, verify_quote_signature, bool,
|
METHOD(pts_t, verify_quote_signature, bool,
|
||||||
private_pts_t *this, chunk_t data, chunk_t signature)
|
private_pts_t *this, chunk_t data, chunk_t signature)
|
||||||
{
|
{
|
||||||
|
/** Implementation using strongswan -> not working */
|
||||||
public_key_t *aik_pub_key;
|
public_key_t *aik_pub_key;
|
||||||
|
|
||||||
aik_pub_key = this->aik->get_public_key(this->aik);
|
aik_pub_key = this->aik->get_public_key(this->aik);
|
||||||
@@ -1257,6 +1230,7 @@ METHOD(pts_t, verify_quote_signature, bool,
|
|||||||
}
|
}
|
||||||
|
|
||||||
aik_pub_key->destroy(aik_pub_key);
|
aik_pub_key->destroy(aik_pub_key);
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1455,7 +1429,7 @@ pts_t *pts_create(bool is_imc)
|
|||||||
.extend_pcr = _extend_pcr,
|
.extend_pcr = _extend_pcr,
|
||||||
.quote_tpm = _quote_tpm,
|
.quote_tpm = _quote_tpm,
|
||||||
.does_pcr_value_match = _does_pcr_value_match,
|
.does_pcr_value_match = _does_pcr_value_match,
|
||||||
.get_quote_digest = _get_quote_digest,
|
.get_quote_info = _get_quote_info,
|
||||||
.verify_quote_signature = _verify_quote_signature,
|
.verify_quote_signature = _verify_quote_signature,
|
||||||
.destroy = _destroy,
|
.destroy = _destroy,
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -60,6 +60,11 @@ typedef struct pcr_entry_t pcr_entry_t;
|
|||||||
*/
|
*/
|
||||||
#define TPM_QUOTE_INFO_LEN 48
|
#define TPM_QUOTE_INFO_LEN 48
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Bitmask Lenght for PCR Composite structure
|
||||||
|
*/
|
||||||
|
#define PCR_MASK_LEN MAX_NUM_PCR / 8
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* PCR Entry structure which contains PCR number and current value
|
* PCR Entry structure which contains PCR number and current value
|
||||||
*/
|
*/
|
||||||
@@ -276,12 +281,12 @@ struct pts_t {
|
|||||||
bool (*does_pcr_value_match)(pts_t *this, chunk_t pcr_after_value);
|
bool (*does_pcr_value_match)(pts_t *this, chunk_t pcr_after_value);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs and returns PCR Quote Digest structure expected from IMC
|
* Constructs and returns TPM Quote Info structure expected from IMC
|
||||||
*
|
*
|
||||||
* @param digest Output variable to store quote digest
|
* @param digest Output variable to store quote digest
|
||||||
* @return FALSE in case of any error, TRUE otherwise
|
* @return FALSE in case of any error, TRUE otherwise
|
||||||
*/
|
*/
|
||||||
bool (*get_quote_digest)(pts_t *this, chunk_t *digest);
|
bool (*get_quote_info)(pts_t *this, chunk_t *quote_info);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs and returns PCR Quote Digest structure expected from IMC
|
* Constructs and returns PCR Quote Digest structure expected from IMC
|
||||||
|
|||||||
Reference in New Issue
Block a user