pts: Verify PCR info during verification and reject mismatches
Replace `set()` with `extend()` in verify methods so the PCR value is independently computed rather than taken from the evidence. Also make `pcr_before` mismatch a hard failure instead of a warning.
This commit is contained in:
committed by
Tobias Brunner
parent
e1609d8159
commit
a885a3da60
@@ -627,7 +627,7 @@ METHOD(pts_component_t, verify, status_t,
|
|||||||
pts_pcr_transform_t transform;
|
pts_pcr_transform_t transform;
|
||||||
pts_pcr_t *pcrs;
|
pts_pcr_t *pcrs;
|
||||||
time_t creation_time;
|
time_t creation_time;
|
||||||
chunk_t measurement, pcr_before, pcr_after;
|
chunk_t measurement, pcr_value, pcr_before, pcr_after;
|
||||||
status_t status = NOT_FOUND;
|
status_t status = NOT_FOUND;
|
||||||
|
|
||||||
this->aik_id = pts->get_aik_id(pts);
|
this->aik_id = pts->get_aik_id(pts);
|
||||||
@@ -646,7 +646,7 @@ METHOD(pts_component_t, verify, status_t,
|
|||||||
if (algo != pcr_algo)
|
if (algo != pcr_algo)
|
||||||
{
|
{
|
||||||
DBG1(DBG_PTS, "received %N measurement hash but PCR bank is %N",
|
DBG1(DBG_PTS, "received %N measurement hash but PCR bank is %N",
|
||||||
pts_meas_algorithm_names, algo, pts_meas_algorithm_names, algo);
|
pts_meas_algorithm_names, algo, pts_meas_algorithm_names, pcr_algo);
|
||||||
return FAILED;
|
return FAILED;
|
||||||
}
|
}
|
||||||
this->pcr_padding = (transform == PTS_PCR_TRANSFORM_SHORT);
|
this->pcr_padding = (transform == PTS_PCR_TRANSFORM_SHORT);
|
||||||
@@ -861,27 +861,25 @@ METHOD(pts_component_t, verify, status_t,
|
|||||||
}
|
}
|
||||||
|
|
||||||
has_pcr_info = evidence->get_pcr_info(evidence, &pcr_before, &pcr_after);
|
has_pcr_info = evidence->get_pcr_info(evidence, &pcr_before, &pcr_after);
|
||||||
if (has_pcr_info)
|
if (has_pcr_info && !chunk_equals_const(pcr_before, pcrs->get(pcrs, pcr)))
|
||||||
{
|
{
|
||||||
if (!chunk_equals_const(pcr_before, pcrs->get(pcrs, pcr)))
|
DBG1(DBG_PTS, "PCR %2u: pcr_before is not equal to register value", pcr);
|
||||||
{
|
return FAILED;
|
||||||
DBG1(DBG_PTS, "PCR %2u: pcr_before is not equal to register value",
|
|
||||||
pcr);
|
|
||||||
}
|
|
||||||
if (pcrs->set(pcrs, pcr, pcr_after))
|
|
||||||
{
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
|
||||||
|
pcr_value = pcrs->extend(pcrs, pcr, measurement);
|
||||||
|
if (!pcr_value.ptr)
|
||||||
{
|
{
|
||||||
pcr_after = pcrs->extend(pcrs, pcr, measurement);
|
return FAILED;
|
||||||
if (pcr_after.ptr)
|
|
||||||
{
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return FAILED;
|
|
||||||
|
if (has_pcr_info && !chunk_equals_const(pcr_after, pcr_value))
|
||||||
|
{
|
||||||
|
DBG1(DBG_PTS, "PCR %2u: pcr_after is not equal to register value", pcr);
|
||||||
|
return FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
METHOD(pts_component_t, finalize, bool,
|
METHOD(pts_component_t, finalize, bool,
|
||||||
|
|||||||
@@ -192,13 +192,13 @@ METHOD(pts_component_t, verify, status_t,
|
|||||||
pts_comp_evidence_t *evidence)
|
pts_comp_evidence_t *evidence)
|
||||||
{
|
{
|
||||||
bool has_pcr_info;
|
bool has_pcr_info;
|
||||||
uint32_t extended_pcr, vid, name DBG_UNUSED;
|
uint32_t pcr, vid, name DBG_UNUSED;
|
||||||
enum_name_t *names DBG_UNUSED;
|
enum_name_t *names DBG_UNUSED;
|
||||||
pts_meas_algorithms_t algo;
|
pts_meas_algorithms_t algo;
|
||||||
pts_pcr_transform_t transform;
|
pts_pcr_transform_t transform;
|
||||||
pts_pcr_t *pcrs;
|
pts_pcr_t *pcrs;
|
||||||
time_t measurement_time;
|
time_t measurement_time;
|
||||||
chunk_t measurement, pcr_before, pcr_after;
|
chunk_t measurement, pcr_value, pcr_before, pcr_after;
|
||||||
status_t status;
|
status_t status;
|
||||||
|
|
||||||
this->aik_id = pts->get_aik_id(pts);
|
this->aik_id = pts->get_aik_id(pts);
|
||||||
@@ -207,8 +207,8 @@ METHOD(pts_component_t, verify, status_t,
|
|||||||
{
|
{
|
||||||
return FAILED;
|
return FAILED;
|
||||||
}
|
}
|
||||||
measurement = evidence->get_measurement(evidence, &extended_pcr,
|
measurement = evidence->get_measurement(evidence, &pcr, &algo, &transform,
|
||||||
&algo, &transform, &measurement_time);
|
&measurement_time);
|
||||||
|
|
||||||
status = this->pts_db->get_comp_measurement_count(this->pts_db,
|
status = this->pts_db->get_comp_measurement_count(this->pts_db,
|
||||||
this->name, this->aik_id, algo,
|
this->name, this->aik_id, algo,
|
||||||
@@ -237,7 +237,7 @@ METHOD(pts_component_t, verify, status_t,
|
|||||||
{
|
{
|
||||||
status = this->pts_db->insert_comp_measurement(this->pts_db,
|
status = this->pts_db->insert_comp_measurement(this->pts_db,
|
||||||
measurement, this->cid, this->aik_id,
|
measurement, this->cid, this->aik_id,
|
||||||
++this->seq_no, extended_pcr, algo);
|
++this->seq_no, pcr, algo);
|
||||||
if (status != SUCCESS)
|
if (status != SUCCESS)
|
||||||
{
|
{
|
||||||
return status;
|
return status;
|
||||||
@@ -248,7 +248,7 @@ METHOD(pts_component_t, verify, status_t,
|
|||||||
{
|
{
|
||||||
status = this->pts_db->check_comp_measurement(this->pts_db,
|
status = this->pts_db->check_comp_measurement(this->pts_db,
|
||||||
measurement, this->cid, this->aik_id,
|
measurement, this->cid, this->aik_id,
|
||||||
++this->seq_no, extended_pcr, algo);
|
++this->seq_no, pcr, algo);
|
||||||
if (status != SUCCESS)
|
if (status != SUCCESS)
|
||||||
{
|
{
|
||||||
return status;
|
return status;
|
||||||
@@ -256,17 +256,22 @@ METHOD(pts_component_t, verify, status_t,
|
|||||||
}
|
}
|
||||||
|
|
||||||
has_pcr_info = evidence->get_pcr_info(evidence, &pcr_before, &pcr_after);
|
has_pcr_info = evidence->get_pcr_info(evidence, &pcr_before, &pcr_after);
|
||||||
if (has_pcr_info)
|
if (has_pcr_info && !chunk_equals_const(pcr_before, pcrs->get(pcrs, pcr)))
|
||||||
{
|
{
|
||||||
if (!chunk_equals_const(pcr_before, pcrs->get(pcrs, extended_pcr)))
|
DBG1(DBG_PTS, "PCR %2u: pcr_before is not equal to register value", pcr);
|
||||||
{
|
return FAILED;
|
||||||
DBG1(DBG_PTS, "PCR %2u: pcr_before is not equal to register value",
|
}
|
||||||
extended_pcr);
|
|
||||||
}
|
pcr_value = pcrs->extend(pcrs, pcr, measurement);
|
||||||
if (pcrs->set(pcrs, extended_pcr, pcr_after))
|
if (!pcr_value.ptr)
|
||||||
{
|
{
|
||||||
return SUCCESS;
|
return FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (has_pcr_info && !chunk_equals_const(pcr_after, pcr_value))
|
||||||
|
{
|
||||||
|
DBG1(DBG_PTS, "PCR %2u: pcr_after is not equal to register value", pcr);
|
||||||
|
return FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
return SUCCESS;
|
return SUCCESS;
|
||||||
|
|||||||
@@ -83,17 +83,17 @@ METHOD(pts_component_t, measure, status_t,
|
|||||||
pts_pcr_transform_t pcr_transform;
|
pts_pcr_transform_t pcr_transform;
|
||||||
pts_meas_algorithms_t hash_algo;
|
pts_meas_algorithms_t hash_algo;
|
||||||
pts_comp_evidence_t *evid;
|
pts_comp_evidence_t *evid;
|
||||||
uint32_t extended_pcr;
|
uint32_t pcr;
|
||||||
time_t measurement_time;
|
time_t measurement_time;
|
||||||
chunk_t measurement, pcr_before, pcr_after;
|
chunk_t measurement, pcr_before, pcr_after;
|
||||||
|
|
||||||
/* Provisional implementation for TGRUB */
|
/* Provisional implementation for TGRUB */
|
||||||
extended_pcr = PCR_DEBUG;
|
pcr = PCR_DEBUG;
|
||||||
time(&measurement_time);
|
time(&measurement_time);
|
||||||
|
|
||||||
if (!pts->read_pcr(pts, extended_pcr, &pcr_after, HASH_SHA1))
|
if (!pts->read_pcr(pts, pcr, &pcr_after, HASH_SHA1))
|
||||||
{
|
{
|
||||||
DBG1(DBG_PTS, "error occurred while reading PCR: %d", extended_pcr);
|
DBG1(DBG_PTS, "error occurred while reading PCR: %d", pcr);
|
||||||
return FAILED;
|
return FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -108,7 +108,7 @@ METHOD(pts_component_t, measure, status_t,
|
|||||||
memset(pcr_before.ptr, 0x00, pcr_before.len);
|
memset(pcr_before.ptr, 0x00, pcr_before.len);
|
||||||
|
|
||||||
evid = *evidence = pts_comp_evidence_create(this->name->clone(this->name),
|
evid = *evidence = pts_comp_evidence_create(this->name->clone(this->name),
|
||||||
this->depth, extended_pcr,
|
this->depth, pcr,
|
||||||
hash_algo, pcr_transform,
|
hash_algo, pcr_transform,
|
||||||
measurement_time, measurement);
|
measurement_time, measurement);
|
||||||
evid->set_pcr_info(evid, pcr_before, pcr_after);
|
evid->set_pcr_info(evid, pcr_before, pcr_after);
|
||||||
@@ -121,22 +121,21 @@ METHOD(pts_component_t, verify, status_t,
|
|||||||
pts_comp_evidence_t *evidence)
|
pts_comp_evidence_t *evidence)
|
||||||
{
|
{
|
||||||
bool has_pcr_info;
|
bool has_pcr_info;
|
||||||
uint32_t extended_pcr;
|
uint32_t pcr;
|
||||||
pts_meas_algorithms_t algo;
|
pts_meas_algorithms_t algo;
|
||||||
pts_pcr_transform_t transform;
|
pts_pcr_transform_t transform;
|
||||||
pts_pcr_t *pcrs;
|
pts_pcr_t *pcrs;
|
||||||
time_t measurement_time;
|
time_t measurement_time;
|
||||||
chunk_t pcr_before, pcr_after;
|
chunk_t measurement, pcr_value, pcr_before, pcr_after;
|
||||||
chunk_t measurement __attribute__((unused));
|
|
||||||
|
|
||||||
pcrs = pts->get_pcrs(pts);
|
pcrs = pts->get_pcrs(pts);
|
||||||
if (!pcrs)
|
if (!pcrs)
|
||||||
{
|
{
|
||||||
return FAILED;
|
return FAILED;
|
||||||
}
|
}
|
||||||
measurement = evidence->get_measurement(evidence, &extended_pcr,
|
measurement = evidence->get_measurement(evidence, &pcr,
|
||||||
&algo, &transform, &measurement_time);
|
&algo, &transform, &measurement_time);
|
||||||
if (extended_pcr != PCR_DEBUG)
|
if (pcr != PCR_DEBUG)
|
||||||
{
|
{
|
||||||
return FAILED;
|
return FAILED;
|
||||||
}
|
}
|
||||||
@@ -144,16 +143,22 @@ METHOD(pts_component_t, verify, status_t,
|
|||||||
/* TODO check measurement in database */
|
/* TODO check measurement in database */
|
||||||
|
|
||||||
has_pcr_info = evidence->get_pcr_info(evidence, &pcr_before, &pcr_after);
|
has_pcr_info = evidence->get_pcr_info(evidence, &pcr_before, &pcr_after);
|
||||||
if (has_pcr_info)
|
if (has_pcr_info && !chunk_equals_const(pcr_before, pcrs->get(pcrs, pcr)))
|
||||||
{
|
{
|
||||||
if (!chunk_equals_const(pcr_before, pcrs->get(pcrs, extended_pcr)))
|
DBG1(DBG_PTS, "PCR %2u: pcr_before is not equal to pcr value", pcr);
|
||||||
{
|
return FAILED;
|
||||||
DBG1(DBG_PTS, "PCR %2u: pcr_before is not equal to pcr value");
|
}
|
||||||
}
|
|
||||||
if (pcrs->set(pcrs, extended_pcr, pcr_after))
|
pcr_value = pcrs->extend(pcrs, pcr, measurement);
|
||||||
{
|
if (!pcr_value.ptr)
|
||||||
return SUCCESS;
|
{
|
||||||
}
|
return FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (has_pcr_info && !chunk_equals_const(pcr_after, pcr_value))
|
||||||
|
{
|
||||||
|
DBG1(DBG_PTS, "PCR %2u: pcr_after is not equal to register value", pcr);
|
||||||
|
return FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
return SUCCESS;
|
return SUCCESS;
|
||||||
|
|||||||
Reference in New Issue
Block a user