diff --git a/src/tss2-fapi/api/Fapi_PcrRead.c b/src/tss2-fapi/api/Fapi_PcrRead.c index b88616e4e..d1ac36afd 100644 --- a/src/tss2-fapi/api/Fapi_PcrRead.c +++ b/src/tss2-fapi/api/Fapi_PcrRead.c @@ -258,7 +258,7 @@ Fapi_PcrRead_Finish( fallthrough; statecase(context->state, PCR_READ_READ_EVENT_LIST); - r = ifapi_eventlog_get_finish(&context->eventlog, &context->io, pcrLog); + r = ifapi_eventlog_get_finish(&context->eventlog, NULL, &context->io, pcrLog); return_try_again(r); goto_if_error(r, "Error getting event log", cleanup); diff --git a/src/tss2-fapi/api/Fapi_Quote.c b/src/tss2-fapi/api/Fapi_Quote.c index 52d2e7726..2f0d851b7 100644 --- a/src/tss2-fapi/api/Fapi_Quote.c +++ b/src/tss2-fapi/api/Fapi_Quote.c @@ -421,6 +421,7 @@ Fapi_Quote_Finish( signed by the TPM. */ r = ifapi_compute_quote_info(sig_key_object, command->tpm_quoted, + &command->fapi_quote_info, quoteInfo); goto_if_error(r, "Create compute quote info.", error_cleanup); @@ -444,7 +445,9 @@ Fapi_Quote_Finish( fallthrough; statecase(context->state, PCR_QUOTE_READ_EVENT_LIST); - r = ifapi_eventlog_get_finish(&context->eventlog, &context->io, + r = ifapi_eventlog_get_finish(&context->eventlog, + &command->fapi_quote_info, + &context->io, &command->pcrLog); return_try_again(r); goto_if_error(r, "Error getting event log", error_cleanup); diff --git a/src/tss2-fapi/api/Fapi_VerifyQuote.c b/src/tss2-fapi/api/Fapi_VerifyQuote.c index 4c7271b09..fda532397 100644 --- a/src/tss2-fapi/api/Fapi_VerifyQuote.c +++ b/src/tss2-fapi/api/Fapi_VerifyQuote.c @@ -266,7 +266,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); @@ -323,7 +322,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); diff --git a/src/tss2-fapi/fapi_int.h b/src/tss2-fapi/fapi_int.h index 55a6cff02..69e4af074 100644 --- a/src/tss2-fapi/fapi_int.h +++ b/src/tss2-fapi/fapi_int.h @@ -191,13 +191,6 @@ typedef struct { TPMS_NV_PUBLIC public; /**< Template for public data */ } IFAPI_NV_TEMPLATE; -/** Type for representing a external public key - */ -typedef struct { - TPMT_SIG_SCHEME sig_scheme; /**< Signature scheme used for quote. */ - TPMS_ATTEST attest; /**< Attestation data from Quote */ -} FAPI_QUOTE_INFO; - /** The states for the FAPI's NV read state */ enum _FAPI_STATE_NV_READ { diff --git a/src/tss2-fapi/ifapi_eventlog.c b/src/tss2-fapi/ifapi_eventlog.c index 8e542eef9..c641ba4bf 100644 --- a/src/tss2-fapi/ifapi_eventlog.c +++ b/src/tss2-fapi/ifapi_eventlog.c @@ -200,10 +200,11 @@ ifapi_eventlog_get_async( TSS2_RC ifapi_eventlog_get_finish( IFAPI_EVENTLOG *eventlog, + FAPI_QUOTE_INFO *fapi_quote_info, IFAPI_IO *io, char **log) { - /* eventlog parameter currently not used */ + /* eventlog parameteifapi_eventlog_get_finishr currently not used */ check_not_null(eventlog); check_not_null(io); check_not_null(log); @@ -230,7 +231,13 @@ ifapi_eventlog_get_finish( goto_if_error(r, "Error serialize policy", error); ifapi_cleanup_event(&event); - } + } + if (fapi_quote_info) { + r = ifapi_calculate_pcr_digest(eventlog->log, + fapi_quote_info); + + goto_if_error(r, "Verify event list.", error); + } *log = strdup(json_object_to_json_string_ext(eventlog->log, JSON_C_TO_STRING_PRETTY)); check_oom(*log); diff --git a/src/tss2-fapi/ifapi_eventlog.h b/src/tss2-fapi/ifapi_eventlog.h index 0ef50abdc..e70893ae8 100644 --- a/src/tss2-fapi/ifapi_eventlog.h +++ b/src/tss2-fapi/ifapi_eventlog.h @@ -84,6 +84,13 @@ typedef struct IFAPI_EVENT { verified. */ } IFAPI_EVENT; +/** Type for representing the quote info and signature scheme for quote. + */ +typedef struct { + TPMT_SIG_SCHEME sig_scheme; /**< Signature scheme used for quote. */ + TPMS_ATTEST attest; /**< Attestation data from Quote */ +} FAPI_QUOTE_INFO; + enum IFAPI_EVENTLOG_STATE { IFAPI_EVENTLOG_STATE_INIT = 0, IFAPI_EVENTLOG_STATE_READING, @@ -120,6 +127,7 @@ ifapi_eventlog_get_async( TSS2_RC ifapi_eventlog_get_finish( IFAPI_EVENTLOG *eventlog, + FAPI_QUOTE_INFO *fapi_quote_info, IFAPI_IO *io, char **log); diff --git a/src/tss2-fapi/ifapi_helpers.c b/src/tss2-fapi/ifapi_helpers.c index 84c499259..7c7188c1f 100644 --- a/src/tss2-fapi/ifapi_helpers.c +++ b/src/tss2-fapi/ifapi_helpers.c @@ -1730,6 +1730,8 @@ ifapi_tpm_to_fapi_signature( * * @param[in] sig_key_object The key object which was used for the quote. * @param[in] tpm_quoted: The attest produced by the quote. + * @param[out] fapi_quote_info Info The representation of the + * attest together with the signing schemed. * @param[out] quoteInfo The character string with the JSON representation of the * attest together with the signing schemed. * @@ -1745,13 +1747,13 @@ TSS2_RC ifapi_compute_quote_info( IFAPI_OBJECT *sig_key_object, TPM2B_ATTEST *tpm_quoted, + FAPI_QUOTE_INFO *fapi_quote_info, char **quoteInfo) { json_object *jso = NULL; TSS2_RC r; size_t offset = 0; TPMS_ATTEST attest_struct; - FAPI_QUOTE_INFO fapi_quote_info; /* The TPM2B_ATTEST contains the marshaled TPMS_ATTEST structure. */ r = Tss2_MU_TPMS_ATTEST_Unmarshal((const uint8_t *) @@ -1759,10 +1761,10 @@ ifapi_compute_quote_info( tpm_quoted->size, &offset, &attest_struct); return_if_error(r, "Unmarshal TPMS_ATTEST."); - fapi_quote_info.attest = attest_struct; + fapi_quote_info->attest = attest_struct; /* The signate scheme will be taken from the key used for qoting. */ - fapi_quote_info.sig_scheme = sig_key_object->misc.key.signing_scheme; - r = ifapi_json_FAPI_QUOTE_INFO_serialize(&fapi_quote_info, &jso); + fapi_quote_info->sig_scheme = sig_key_object->misc.key.signing_scheme; + r = ifapi_json_FAPI_QUOTE_INFO_serialize(fapi_quote_info, &jso); return_if_error(r, "Conversion to TPM2B_ATTEST to JSON."); /* The intermediate structure of type FAPI_QOTE_INFO will be serialized. */ @@ -2101,10 +2103,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 @@ -2122,20 +2125,20 @@ 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++) { @@ -2143,11 +2146,11 @@ ifapi_calculate_pcrs( 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; } } } @@ -2180,7 +2183,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) { @@ -2197,6 +2200,42 @@ 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], "e_digest->buffer[0], + pcr_digest.size) == 0) { + if (i_evt < (n_events - 1)) { + /* delete the events added after the quote */ + if (json_object_array_del_idx(jso_event_list, i_evt + 1, + n_events - i_evt - 1)) { + goto_error(r, TSS2_FAPI_RC_GENERAL_FAILURE, + "Can't delete remaining eventsize", error_cleanup); + } + } + 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; } } @@ -2230,22 +2269,17 @@ 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; 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 = "e_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: @@ -2265,35 +2299,15 @@ 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); - - /* 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; + r = ifapi_calculate_pcrs(jso_event_list, pcr_selection, pcr_digest_hash_alg, + "e_info->attest.attested.quote.pcrDigest, + &pcrs[0]); + goto_if_error(r, "Compute PCRs", error_cleanup); - /* Compare the digest from the event list with the digest from the attest */ - if (memcmp(&pcr_digest->buffer[0], "e_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) ifapi_crypto_hash_abort(&cryptoContext); - ifapi_cleanup_event(&event); return r; } diff --git a/src/tss2-fapi/ifapi_helpers.h b/src/tss2-fapi/ifapi_helpers.h index 3a9244183..ef4482985 100644 --- a/src/tss2-fapi/ifapi_helpers.h +++ b/src/tss2-fapi/ifapi_helpers.h @@ -139,6 +139,7 @@ TSS2_RC ifapi_compute_quote_info( IFAPI_OBJECT *sig_key_object, TPM2B_ATTEST *tpm_quoted, + FAPI_QUOTE_INFO *fapi_quote_info, char **quoteInfo); TSS2_RC @@ -173,16 +174,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( diff --git a/test/unit/fapi-eventlog.c b/test/unit/fapi-eventlog.c index 1063eecd6..dba463ade 100644 --- a/test/unit/fapi-eventlog.c +++ b/test/unit/fapi-eventlog.c @@ -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 = @@ -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 */