Skip to content

Commit

Permalink
FAPI: Fix synchronization eventlog.
Browse files Browse the repository at this point in the history
After the execution of a quote the ima eventlog can be
extended before the read of the log. Therefore every entry
in the eventlog is checked whether the digest in
the attest matches the current digest computed from the
reconstructed pcrs. If yes success is returned and
the following events are ignored.

Signed-off-by: Juergen Repp <juergen_repp@web.de>
  • Loading branch information
JuergenReppSIT committed Dec 29, 2023
1 parent 8eba94c commit 1fe18e0
Show file tree
Hide file tree
Showing 4 changed files with 56 additions and 51 deletions.
3 changes: 1 addition & 2 deletions src/tss2-fapi/api/Fapi_VerifyQuote.c
Original file line number Diff line number Diff line change
Expand Up @@ -262,7 +262,6 @@ Fapi_VerifyQuote_Finish(
TSS2_RC r;
IFAPI_OBJECT key_object;
TPM2B_ATTEST attest2b;
TPM2B_DIGEST pcr_digest;

/* Check for NULL parameters */
check_not_null(context);
Expand Down Expand Up @@ -319,7 +318,7 @@ Fapi_VerifyQuote_Finish(

/* Recalculate and verify the PCR digests. */
r = ifapi_calculate_pcr_digest(command->event_list,
&command->fapi_quote_info, &pcr_digest);
&command->fapi_quote_info);

goto_if_error(r, "Verify event list.", error_cleanup);

Expand Down
90 changes: 48 additions & 42 deletions src/tss2-fapi/ifapi_helpers.c
Original file line number Diff line number Diff line change
Expand Up @@ -2101,10 +2101,11 @@ ifapi_extend_pcr(
return r;
}

/** Compute pcr values from event list
/** Compute pcr values from event list and verify quote digest.
*
* The event list is used to compute the PCR values corresponding
* to this event list.
* to this event list. If a quote digest is passed success will
* be returned if the computed pcr digest matches the quote digest.
* @param[in] jso_event_list The event list in JSON representation.
* @param[in] pcr_selection The definition of the used pcrs.
* @param[out] pcrs The computed pcr list
Expand All @@ -2122,32 +2123,32 @@ TSS2_RC
ifapi_calculate_pcrs(
json_object *jso_event_list,
const TPML_PCR_SELECTION *pcr_selection,
IFAPI_PCR_REG pcrs[],
size_t *n_pcrs)
TPMI_ALG_HASH pcr_digest_hash_alg,
const TPM2B_DIGEST *quote_digest,
IFAPI_PCR_REG *pcrs)
{
TSS2_RC r = TSS2_RC_SUCCESS;
IFAPI_CRYPTO_CONTEXT_BLOB *cryptoContext = NULL;
size_t i, pcr, i_evt, hash_size, n_events = 0;

size_t n_pcrs = 0;
TPM2B_DIGEST pcr_digest;
json_object *jso;
IFAPI_EVENT event;
bool found_hcrtm = false;
UINT8 locality = 0;

*n_pcrs = 0;

/* Initialize used pcrs */
for (i = 0; i < pcr_selection->count; i++) {
for (pcr = 0; pcr < TPM2_MAX_PCRS; pcr++) {
uint8_t byte_idx = pcr / 8;
uint8_t flag = 1 << (pcr % 8);
if (flag & pcr_selection->pcrSelections[i].pcrSelect[byte_idx]) {
hash_size = ifapi_hash_get_digest_size(pcr_selection->pcrSelections[i].hash);
pcrs[*n_pcrs].pcr = pcr;
pcrs[*n_pcrs].bank = pcr_selection->pcrSelections[i].hash;
pcrs[*n_pcrs].value.size = hash_size;
memset(&pcrs[*n_pcrs].value.buffer[0], 0, hash_size);
*n_pcrs += 1;
pcrs[n_pcrs].pcr = pcr;
pcrs[n_pcrs].bank = pcr_selection->pcrSelections[i].hash;
pcrs[n_pcrs].value.size = hash_size;
memset(&pcrs[n_pcrs].value.buffer[0], 0, hash_size);
n_pcrs += 1;
}
}
}
Expand Down Expand Up @@ -2180,7 +2181,7 @@ ifapi_calculate_pcrs(
}
}

for (i = 0; i < *n_pcrs; i++) {
for (i = 0; i < n_pcrs; i++) {
if (pcrs[i].pcr == event.pcr) {
if (event.content_type == IFAPI_PC_CLIENT && event.pcr == 0) {
if (event.content.firmware_event.event_type == EV_EFI_HCRTM_EVENT) {
Expand All @@ -2197,6 +2198,34 @@ ifapi_calculate_pcrs(
}
}
ifapi_cleanup_event(&event);

/* Compute digest for the used pcrs */
if (quote_digest) {
r = ifapi_crypto_hash_start(&cryptoContext, pcr_digest_hash_alg);
return_if_error(r, "crypto hash start");

for (i = 0; i < n_pcrs; i++) {
HASH_UPDATE_BUFFER(cryptoContext, &pcrs[i].value.buffer, pcrs[i].value.size,
r, error_cleanup);
}
r = ifapi_crypto_hash_finish(&cryptoContext,
(uint8_t *) &pcr_digest.buffer[0],
&hash_size);
return_if_error(r, "crypto hash finish");
pcr_digest.size = hash_size;

/* Compare the digest from the event list with the digest from the attest */
if (memcmp(&pcr_digest.buffer[0], &quote_digest->buffer[0],
pcr_digest.size) == 0) {
break;
} else {
ifapi_crypto_hash_abort(&cryptoContext);
}
}
}
if (i_evt == n_events && quote_digest) {
/* Quote digest was not found. */
r = TSS2_FAPI_RC_SIGNATURE_VERIFICATION_FAILED;
}
}

Expand Down Expand Up @@ -2230,22 +2259,18 @@ ifapi_calculate_pcrs(
TSS2_RC
ifapi_calculate_pcr_digest(
json_object *jso_event_list,
const FAPI_QUOTE_INFO *quote_info,
TPM2B_DIGEST *pcr_digest)
const FAPI_QUOTE_INFO *quote_info)
{
TSS2_RC r;
IFAPI_CRYPTO_CONTEXT_BLOB *cryptoContext = NULL;
IFAPI_PCR_REG pcrs[TPM2_MAX_PCRS];
size_t i, hash_size, n_pcrs = 0;

IFAPI_EVENT event;
IFAPI_PCR_REG pcrs[TPM2_MAX_PCRS];

const TPML_PCR_SELECTION *pcr_selection;
TPMI_ALG_HASH pcr_digest_hash_alg;

/* Get some data from the quote info for easier access */
pcr_selection = &quote_info->attest.attested.quote.pcrSelect;
pcr_digest->size = quote_info->attest.attested.quote.pcrDigest.size;

switch (quote_info->sig_scheme.scheme) {
case TPM2_ALG_RSAPSS:
Expand All @@ -2265,30 +2290,11 @@ ifapi_calculate_pcr_digest(
return TSS2_FAPI_RC_BAD_VALUE;
}

r = ifapi_calculate_pcrs(jso_event_list, pcr_selection, &pcrs[0], &n_pcrs);
goto_if_error(r, "Compute PCRFs", error_cleanup);
r = ifapi_calculate_pcrs(jso_event_list, pcr_selection, pcr_digest_hash_alg,
&quote_info->attest.attested.quote.pcrDigest,
&pcrs[0]);
goto_if_error(r, "Compute PCRs", error_cleanup);

/* Compute digest for the used pcrs */
r = ifapi_crypto_hash_start(&cryptoContext, pcr_digest_hash_alg);
return_if_error(r, "crypto hash start");

for (i = 0; i < n_pcrs; i++) {
HASH_UPDATE_BUFFER(cryptoContext, &pcrs[i].value.buffer, pcrs[i].value.size,
r, error_cleanup);
}
r = ifapi_crypto_hash_finish(&cryptoContext,
(uint8_t *) &pcr_digest->buffer[0],
&hash_size);
return_if_error(r, "crypto hash finish");
pcr_digest->size = hash_size;

/* Compare the digest from the event list with the digest from the attest */
if (memcmp(&pcr_digest->buffer[0], &quote_info->attest.attested.quote.pcrDigest.buffer[0],
pcr_digest->size) != 0) {
goto_error(r, TSS2_FAPI_RC_SIGNATURE_VERIFICATION_FAILED,
"The digest computed from event list does not match the attest.",
error_cleanup);
}

error_cleanup:
if (cryptoContext)
Expand Down
11 changes: 6 additions & 5 deletions src/tss2-fapi/ifapi_helpers.h
Original file line number Diff line number Diff line change
Expand Up @@ -173,16 +173,17 @@ ifapi_filter_pcr_selection_by_index(
const TPM2_HANDLE *pcr_index,
size_t pcr_count);

TSS2_RC ifapi_calculate_pcrs(
TSS2_RC
ifapi_calculate_pcrs(
json_object *jso_event_list,
const TPML_PCR_SELECTION *pcr_selection,
IFAPI_PCR_REG pcrs[],
size_t *n_pcrs);
TPMI_ALG_HASH pcr_digest_hash_alg,
const TPM2B_DIGEST *quote_digest,
IFAPI_PCR_REG *pcrs);

TSS2_RC ifapi_calculate_pcr_digest(
json_object *jso_event_list,
const FAPI_QUOTE_INFO *quote_info,
TPM2B_DIGEST *pcr_digest);
const FAPI_QUOTE_INFO *quote_info);

TSS2_RC
ifapi_compute_policy_digest(
Expand Down
3 changes: 1 addition & 2 deletions test/unit/fapi-eventlog.c
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,6 @@ check_eventlog_pcr0(const char *file, uint32_t *pcr_list, size_t pcr_list_size,
uint8_t *eventlog;
size_t size;
json_object *json_event_list = NULL;
size_t n_pcrs;
IFAPI_PCR_REG pcrs[TPM2_MAX_PCRS];

TPML_PCR_SELECTION pcr_selection =
Expand Down Expand Up @@ -166,7 +165,7 @@ check_eventlog_pcr0(const char *file, uint32_t *pcr_list, size_t pcr_list_size,
r = ifapi_get_tcg_firmware_event_list(file, pcr_list, pcr_list_size, &json_event_list);
assert_int_equal (r, TSS2_RC_SUCCESS);

r = ifapi_calculate_pcrs(json_event_list, &pcr_selection, &pcrs[0], &n_pcrs);
r = ifapi_calculate_pcrs(json_event_list, &pcr_selection, TPM2_ALG_SHA1, NULL, &pcrs[0]);
assert_int_equal (r, TSS2_RC_SUCCESS);

/* Compare with the pcr0 value got from system with HCRTM events */
Expand Down

0 comments on commit 1fe18e0

Please sign in to comment.