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:
Andreas Steffen
2026-07-23 10:26:08 +02:00
committed by Tobias Brunner
parent e1609d8159
commit a885a3da60
3 changed files with 62 additions and 54 deletions
+17 -19
View File
@@ -627,7 +627,7 @@ METHOD(pts_component_t, verify, status_t,
pts_pcr_transform_t transform;
pts_pcr_t *pcrs;
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;
this->aik_id = pts->get_aik_id(pts);
@@ -646,7 +646,7 @@ METHOD(pts_component_t, verify, status_t,
if (algo != pcr_algo)
{
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;
}
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);
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);
}
if (pcrs->set(pcrs, pcr, pcr_after))
{
return status;
}
DBG1(DBG_PTS, "PCR %2u: pcr_before is not equal to register value", pcr);
return FAILED;
}
else
pcr_value = pcrs->extend(pcrs, pcr, measurement);
if (!pcr_value.ptr)
{
pcr_after = pcrs->extend(pcrs, pcr, measurement);
if (pcr_after.ptr)
{
return status;
}
return FAILED;
}
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,
+21 -16
View File
@@ -192,13 +192,13 @@ METHOD(pts_component_t, verify, status_t,
pts_comp_evidence_t *evidence)
{
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;
pts_meas_algorithms_t algo;
pts_pcr_transform_t transform;
pts_pcr_t *pcrs;
time_t measurement_time;
chunk_t measurement, pcr_before, pcr_after;
chunk_t measurement, pcr_value, pcr_before, pcr_after;
status_t status;
this->aik_id = pts->get_aik_id(pts);
@@ -207,8 +207,8 @@ METHOD(pts_component_t, verify, status_t,
{
return FAILED;
}
measurement = evidence->get_measurement(evidence, &extended_pcr,
&algo, &transform, &measurement_time);
measurement = evidence->get_measurement(evidence, &pcr, &algo, &transform,
&measurement_time);
status = this->pts_db->get_comp_measurement_count(this->pts_db,
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,
measurement, this->cid, this->aik_id,
++this->seq_no, extended_pcr, algo);
++this->seq_no, pcr, algo);
if (status != SUCCESS)
{
return status;
@@ -248,7 +248,7 @@ METHOD(pts_component_t, verify, status_t,
{
status = this->pts_db->check_comp_measurement(this->pts_db,
measurement, this->cid, this->aik_id,
++this->seq_no, extended_pcr, algo);
++this->seq_no, pcr, algo);
if (status != SUCCESS)
{
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);
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",
extended_pcr);
}
if (pcrs->set(pcrs, extended_pcr, pcr_after))
{
return SUCCESS;
}
DBG1(DBG_PTS, "PCR %2u: pcr_before is not equal to register value", pcr);
return FAILED;
}
pcr_value = pcrs->extend(pcrs, pcr, measurement);
if (!pcr_value.ptr)
{
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;
+24 -19
View File
@@ -83,17 +83,17 @@ METHOD(pts_component_t, measure, status_t,
pts_pcr_transform_t pcr_transform;
pts_meas_algorithms_t hash_algo;
pts_comp_evidence_t *evid;
uint32_t extended_pcr;
uint32_t pcr;
time_t measurement_time;
chunk_t measurement, pcr_before, pcr_after;
/* Provisional implementation for TGRUB */
extended_pcr = PCR_DEBUG;
pcr = PCR_DEBUG;
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;
}
@@ -108,7 +108,7 @@ METHOD(pts_component_t, measure, status_t,
memset(pcr_before.ptr, 0x00, pcr_before.len);
evid = *evidence = pts_comp_evidence_create(this->name->clone(this->name),
this->depth, extended_pcr,
this->depth, pcr,
hash_algo, pcr_transform,
measurement_time, measurement);
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)
{
bool has_pcr_info;
uint32_t extended_pcr;
uint32_t pcr;
pts_meas_algorithms_t algo;
pts_pcr_transform_t transform;
pts_pcr_t *pcrs;
time_t measurement_time;
chunk_t pcr_before, pcr_after;
chunk_t measurement __attribute__((unused));
chunk_t measurement, pcr_value, pcr_before, pcr_after;
pcrs = pts->get_pcrs(pts);
if (!pcrs)
{
return FAILED;
}
measurement = evidence->get_measurement(evidence, &extended_pcr,
measurement = evidence->get_measurement(evidence, &pcr,
&algo, &transform, &measurement_time);
if (extended_pcr != PCR_DEBUG)
if (pcr != PCR_DEBUG)
{
return FAILED;
}
@@ -144,16 +143,22 @@ METHOD(pts_component_t, verify, status_t,
/* TODO check measurement in database */
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");
}
if (pcrs->set(pcrs, extended_pcr, pcr_after))
{
return SUCCESS;
}
DBG1(DBG_PTS, "PCR %2u: pcr_before is not equal to pcr value", pcr);
return FAILED;
}
pcr_value = pcrs->extend(pcrs, pcr, measurement);
if (!pcr_value.ptr)
{
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;