From cc18b1a4771784e9890f1e36ddd6996b5c9edcd9 Mon Sep 17 00:00:00 2001 From: Andreas Fuchs Date: Wed, 31 Jul 2024 15:18:40 +0200 Subject: [PATCH 1/2] Test: Reset PCR16 upon test exit Signed-off-by: Andreas Fuchs --- test/integration/esys-event-sequence-complete.int.c | 8 ++++++++ test/integration/esys-pcr-basic.int.c | 7 +++++++ test/integration/fapi-quote-destructive-eventlog.int.c | 7 ++++--- test/integration/fapi-quote-with-primary.int.c | 7 ++++--- test/integration/fapi-quote.int.c | 7 ++++--- 5 files changed, 27 insertions(+), 9 deletions(-) diff --git a/test/integration/esys-event-sequence-complete.int.c b/test/integration/esys-event-sequence-complete.int.c index 91ee9525c..66e075d4e 100644 --- a/test/integration/esys-event-sequence-complete.int.c +++ b/test/integration/esys-event-sequence-complete.int.c @@ -82,6 +82,14 @@ test_esys_event_sequence_complete(ESYS_CONTEXT * esys_context) &results); goto_if_error(r, "Error: EventSequenceComplete", error); + r = Esys_PCR_Reset( + esys_context, + pcrHandle_handle, + ESYS_TR_PASSWORD, + ESYS_TR_NONE, + ESYS_TR_NONE); + goto_if_error(r, "Error: PCR_Reset", error); + Esys_Free(results); return EXIT_SUCCESS; diff --git a/test/integration/esys-pcr-basic.int.c b/test/integration/esys-pcr-basic.int.c index 38fa5ef36..14e9afc6f 100644 --- a/test/integration/esys-pcr-basic.int.c +++ b/test/integration/esys-pcr-basic.int.c @@ -112,7 +112,14 @@ test_esys_pcr_basic(ESYS_CONTEXT * esys_context) ESYS_TR_NONE, &eventData, &digestsEvent); + goto_if_error(r, "Error: PCR_Reset", error); + r = Esys_PCR_Reset( + esys_context, + pcrHandle_handle, + ESYS_TR_PASSWORD, + ESYS_TR_NONE, + ESYS_TR_NONE); goto_if_error(r, "Error: PCR_Reset", error); TPMI_YES_NO allocationSuccess; diff --git a/test/integration/fapi-quote-destructive-eventlog.int.c b/test/integration/fapi-quote-destructive-eventlog.int.c index 3e5da1085..b6a9ad930 100644 --- a/test/integration/fapi-quote-destructive-eventlog.int.c +++ b/test/integration/fapi-quote-destructive-eventlog.int.c @@ -1043,9 +1043,6 @@ test_fapi_quote_destructive(FAPI_CONTEXT *context) 0x00, 0x00, }; - r = pcr_reset(context, 16); - goto_if_error(r, "Error pcr_reset", error); - r = Fapi_PcrExtend(context, 16, data, EVENT_SIZE, "{ \"test\": \"myfile\" }"); goto_if_error(r, "Error Fapi_PcrExtend", error); @@ -1118,6 +1115,9 @@ test_fapi_quote_destructive(FAPI_CONTEXT *context) ASSERT(pathlist != NULL); ASSERT(strlen(pathlist) > ASSERT_SIZE); + r = pcr_reset(context, 16); + goto_if_error(r, "Error pcr_reset", error); + r = Fapi_Delete(context, "/"); goto_if_error(r, "Error Fapi_Delete", error); @@ -1136,6 +1136,7 @@ test_fapi_quote_destructive(FAPI_CONTEXT *context) return EXIT_SUCCESS; error: + pcr_reset(context, 16); Fapi_Delete(context, "/"); SAFE_FREE(pubkey_pem); SAFE_FREE(signature); diff --git a/test/integration/fapi-quote-with-primary.int.c b/test/integration/fapi-quote-with-primary.int.c index 468376d31..93529b6f1 100644 --- a/test/integration/fapi-quote-with-primary.int.c +++ b/test/integration/fapi-quote-with-primary.int.c @@ -80,9 +80,6 @@ test_fapi_quote(FAPI_CONTEXT *context) 0x00, 0x00, }; - r = pcr_reset(context, 16); - goto_if_error(r, "Error pcr_reset", error); - r = Fapi_PcrExtend(context, 16, data, EVENT_SIZE, "{ \"test\": \"myfile\" }"); goto_if_error(r, "Error Fapi_PcrExtend", error); @@ -289,6 +286,9 @@ test_fapi_quote(FAPI_CONTEXT *context) ASSERT(strlen(pathlist) > ASSERT_SIZE); LOG_INFO("\nPathlist: %s\n", pathlist); + r = pcr_reset(context, 16); + goto_if_error(r, "Error pcr_reset", error); + r = Fapi_Delete(context, "/"); goto_if_error(r, "Error Fapi_Delete", error); @@ -305,6 +305,7 @@ test_fapi_quote(FAPI_CONTEXT *context) return EXIT_SUCCESS; error: + pcr_reset(context, 16); Fapi_Delete(context, "/"); if (jso) json_object_put(jso); diff --git a/test/integration/fapi-quote.int.c b/test/integration/fapi-quote.int.c index b112c669e..44e7bfefd 100644 --- a/test/integration/fapi-quote.int.c +++ b/test/integration/fapi-quote.int.c @@ -81,9 +81,6 @@ test_fapi_quote(FAPI_CONTEXT *context) 0x00, 0x00, }; - r = pcr_reset(context, 16); - goto_if_error(r, "Error pcr_reset", error); - r = Fapi_PcrExtend(context, 16, data, EVENT_SIZE, "{ \"test\": \"myfile\" }"); goto_if_error(r, "Error Fapi_PcrExtend", error); @@ -341,6 +338,9 @@ test_fapi_quote(FAPI_CONTEXT *context) goto error; } + r = pcr_reset(context, 16); + goto_if_error(r, "Error pcr_reset", error); + r = Fapi_Delete(context, "/"); goto_if_error(r, "Error Fapi_Delete", error); @@ -357,6 +357,7 @@ test_fapi_quote(FAPI_CONTEXT *context) return EXIT_SUCCESS; error: + pcr_reset(context, 16); Fapi_Delete(context, "/"); if (jso) json_object_put(jso); From 6a78aa7094eb97ce679638c433bcf0b727767467 Mon Sep 17 00:00:00 2001 From: Andreas Fuchs Date: Wed, 31 Jul 2024 11:28:42 +0200 Subject: [PATCH 2/2] Test: Add pre and post check for PCR16 to be empty The test harness for integration tests now check before and after every integration test invocation if PCR16 is empty to begin but also after the test. Signed-off-by: Andreas Fuchs --- test/integration/test-common.c | 80 +++++++++++++++++++++++++++++++++- 1 file changed, 79 insertions(+), 1 deletion(-) diff --git a/test/integration/test-common.c b/test/integration/test-common.c index bc459569a..8b87737a2 100644 --- a/test/integration/test-common.c +++ b/test/integration/test-common.c @@ -4,6 +4,8 @@ * * All rights reserved. ***********************************************************************/ +#include "tss2_sys.h" + #ifdef HAVE_CONFIG_H #include "config.h" // IWYU pragma: keep #endif @@ -44,7 +46,7 @@ struct { }; struct tpm_state { - TPMS_CAPABILITY_DATA capabilities[7]; + TPMS_CAPABILITY_DATA capabilities[sizeof(capabilities_to_dump) / sizeof(capabilities_to_dump[0])]; }; /** Define a proxy tcti that returns yielded on every second invocation @@ -235,6 +237,40 @@ transient_empty(TSS2_SYS_CONTEXT *sys_ctx) return EXIT_SUCCESS; } +int +pcr16_empty(TSS2_SYS_CONTEXT *sys_ctx) +{ + TSS2_RC rc; + TPML_DIGEST pcr_values = { 0 }; + TPML_PCR_SELECTION pcr_selection = { .count=1, .pcrSelections = { { .hash = TPM2_ALG_SHA256, .sizeofSelect = 3, .pcrSelect = { 0 } } } }; + pcr_selection.pcrSelections[0].pcrSelect[(16 / 8)] = 1 << (16 % 8); + + do { + rc = Tss2_Sys_PCR_Read(sys_ctx, NULL, + &pcr_selection, NULL, NULL, + &pcr_values, + NULL); + } while (rc == TPM2_RC_YIELDED); // TODO also for other cmds? + if (rc != TSS2_RC_SUCCESS) { + LOG_ERROR("TPM2_PCR_Read failed: 0x%" PRIx32, rc); + return EXIT_ERROR; + } + + if (pcr_values.count != 1) { + LOG_ERROR("TPM2_PCR_Read for PCR 16 in SHA256 did not return a value"); + } + + for (UINT16 i = 0; i < pcr_values.digests[0].size; i++) { + if (pcr_values.digests[0].buffer[i] != 0x00) { + LOGBLOB_ERROR(&pcr_values.digests[0].buffer[0], pcr_values.digests[0].size, + "PCR 16 in SHA256 is not 0x000..000"); + return EXIT_ERROR; + } + } + + return EXIT_SUCCESS; +} + int dumpstate(TSS2_SYS_CONTEXT *sys_ctx, tpm_state *state_first, bool compare) { @@ -390,6 +426,13 @@ test_sys_checks_pre(TSS2_TEST_SYS_CONTEXT *test_ctx) return ret; } + LOG_DEBUG("Running System API pre-test checks: pcr16 empty"); + ret = pcr16_empty(test_ctx->sys_ctx); + if (ret != EXIT_SUCCESS) { + LOG_ERROR("PCR16 is not empty"); + return ret; + } + return EXIT_SUCCESS; } @@ -398,6 +441,13 @@ test_sys_checks_post(TSS2_TEST_SYS_CONTEXT *test_ctx) { int ret; + LOG_DEBUG("Running System API pre-test checks: transient handles empty"); + ret = transient_empty(test_ctx->sys_ctx); + if (ret != EXIT_SUCCESS) { + LOG_ERROR("TPM contains transient objects."); + return ret; + } + LOG_DEBUG("Running System API post-test checks: dump capabilities"); ret = dumpstate(test_ctx->sys_ctx, test_ctx->tpm_state, 1); if (ret != EXIT_SUCCESS) { @@ -405,6 +455,13 @@ test_sys_checks_post(TSS2_TEST_SYS_CONTEXT *test_ctx) return ret; } + LOG_DEBUG("Running System API post-test checks: pcr16 empty"); + ret = pcr16_empty(test_ctx->sys_ctx); + if (ret != EXIT_SUCCESS) { + LOG_ERROR("PCR16 is not empty"); + return ret; + } + return EXIT_SUCCESS; } @@ -533,6 +590,13 @@ test_esys_checks_pre(TSS2_TEST_ESYS_CONTEXT *test_ctx) return ret; } + LOG_DEBUG("Running System API pre-test checks: pcr16 empty"); + ret = pcr16_empty(sys_context); + if (ret != EXIT_SUCCESS) { + LOG_ERROR("PCR16 is not empty"); + return ret; + } + return EXIT_SUCCESS; } @@ -549,6 +613,13 @@ test_esys_checks_post(TSS2_TEST_ESYS_CONTEXT *test_ctx) return EXIT_ERROR; } + LOG_DEBUG("Running System API pre-test checks: transient handles empty"); + ret = transient_empty(sys_context); + if (ret != EXIT_SUCCESS) { + LOG_ERROR("TPM contains transient objects."); + return ret; + } + LOG_DEBUG("Running System API post-test checks: dump capabilities"); ret = dumpstate(sys_context, test_ctx->tpm_state, 1); if (ret != EXIT_SUCCESS) { @@ -556,6 +627,13 @@ test_esys_checks_post(TSS2_TEST_ESYS_CONTEXT *test_ctx) return ret; } + LOG_DEBUG("Running System API pre-test checks: pcr16 empty"); + ret = pcr16_empty(sys_context); + if (ret != EXIT_SUCCESS) { + LOG_ERROR("PCR16 is not empty"); + return ret; + } + return EXIT_SUCCESS; }