diff --git a/SOURCES/0001-Fix-handling-of-testResult-in-tpm2_gettestresult.patch b/SOURCES/0001-Fix-handling-of-testResult-in-tpm2_gettestresult.patch new file mode 100644 index 0000000..e119e8d --- /dev/null +++ b/SOURCES/0001-Fix-handling-of-testResult-in-tpm2_gettestresult.patch @@ -0,0 +1,26 @@ +From ff26c05d928519f9ae8442d9fd6458fbebb3c518 Mon Sep 17 00:00:00 2001 +From: "wenxin.leong" +Date: Wed, 15 May 2024 18:58:21 -0700 +Subject: [PATCH 1/8] Fix handling of testResult in tpm2_gettestresult + +Signed-off-by: wenxin.leong +--- + tools/tpm2_gettestresult.c | 2 -- + 1 file changed, 2 deletions(-) + +diff --git a/tools/tpm2_gettestresult.c b/tools/tpm2_gettestresult.c +index 24a5caf6..29f913a3 100644 +--- a/tools/tpm2_gettestresult.c ++++ b/tools/tpm2_gettestresult.c +@@ -35,8 +35,6 @@ static tool_rc tpm2_tool_onrun(ESYS_CONTEXT *ectx, tpm2_option_flags flags) { + tpm2_tool_output("status: "); + print_yaml_indent(1); + +- status &= TPM2_RC_TESTING; +- + switch (status) { + case TPM2_RC_SUCCESS: + tpm2_tool_output("success"); +-- +2.49.0 + diff --git a/SOURCES/0001-tpm2_sessionconfig-fix-usage-of-disable-continuesess.patch b/SOURCES/0001-tpm2_sessionconfig-fix-usage-of-disable-continuesess.patch new file mode 100644 index 0000000..fc9903f --- /dev/null +++ b/SOURCES/0001-tpm2_sessionconfig-fix-usage-of-disable-continuesess.patch @@ -0,0 +1,131 @@ +From c2dff7cfac16a857fcd5161d6e171483221ab003 Mon Sep 17 00:00:00 2001 +From: Juergen Repp +Date: Sun, 17 Dec 2023 09:53:01 +0100 +Subject: [PATCH 1/6] tpm2_sessionconfig fix usage of --disable-continuesession + +Conflicts: context change due to missing 6169d8c22 + +If continue session was disabled a error did occur in the function for +restoring the session context. +Now after usage of an session with continue session disabled the +context will not be saved and the session context file will be +deleted. +In one integration test continue session is now disabled and the +flush for this session is removed. + +Fixes: #3295 + +Signed-off-by: Juergen Repp +--- + lib/tpm2_session.c | 45 +++++++++++++++++++++++--------- + test/integration/tests/unseal.sh | 7 +++-- + 2 files changed, 37 insertions(+), 15 deletions(-) + +diff --git a/lib/tpm2_session.c b/lib/tpm2_session.c +index 60b8643b..3e5503db 100644 +--- a/lib/tpm2_session.c ++++ b/lib/tpm2_session.c +@@ -35,6 +35,7 @@ struct tpm2_session { + char *path; + ESYS_CONTEXT *ectx; + bool is_final; ++ bool delete; + } internal; + }; + +@@ -290,18 +291,23 @@ tool_rc tpm2_session_restore(ESYS_CONTEXT *ctx, const char *path, bool is_final, + dup_path = NULL; + + TPMA_SESSION attrs = 0; ++ s->internal.delete = false; ++ s->internal.is_final = is_final; ++ *session = s; + + if (ctx) { +- + /* hack this in here, should be done when starting the session */ + tmp_rc = tpm2_sess_get_attributes(ctx, handle, &attrs); +- UNUSED(tmp_rc); ++ if (tmp_rc != tool_rc_success) { ++ rc = tmp_rc; ++ LOG_ERR("Can't get session attributes."); ++ goto out; ++ } ++ if ((attrs & TPMA_SESSION_CONTINUESESSION) == 0) { ++ s->internal.delete = true; ++ } + } + +- s->internal.is_final = is_final; +- +- *session = s; +- + LOG_INFO("Restored session: ESYS_TR(0x%x) attrs(0x%x)", handle, attrs); + + rc = tool_rc_success; +@@ -341,22 +347,35 @@ tool_rc tpm2_session_close(tpm2_session **s) { + } + + const char *path = session->internal.path; +- FILE *session_file = path ? fopen(path, "w+b") : NULL; +- if (path && !session_file) { +- LOG_ERR("Could not open path \"%s\", due to error: \"%s\"", path, +- strerror(errno)); +- rc = tool_rc_general_error; +- goto out; +- } + + bool flush = path ? session->internal.is_final : true; + if (flush) { + rc = tpm2_flush_context(session->internal.ectx, + session->output.session_handle); + /* done, use rc to indicate status */ ++ goto out2; ++ } ++ ++ if ((*s)->internal.delete && path) { ++ if (remove(path)) { ++ LOG_ERR("File \"%s\" can't be deleted.", path); ++ rc = tool_rc_general_error; ++ goto out2; ++ } else { ++ rc = tool_rc_success; ++ goto out2; ++ } ++ } ++ ++ FILE *session_file = path ? fopen(path, "w+b") : NULL; ++ if (path && !session_file) { ++ LOG_ERR("Could not open path \"%s\", due to error: \"%s\"", path, ++ strerror(errno)); ++ rc = tool_rc_general_error; + goto out; + } + ++ + /* + * Now write the session_type, handle and auth hash data to disk + */ +diff --git a/test/integration/tests/unseal.sh b/test/integration/tests/unseal.sh +index dd6c2bc6..d0f7104f 100644 +--- a/test/integration/tests/unseal.sh ++++ b/test/integration/tests/unseal.sh +@@ -152,10 +152,13 @@ tpm2 sessionconfig enc_session.ctx --disable-encrypt + tpm2 create -Q -C prim.ctx -u seal_key.pub -r seal_key.priv -c seal_key.ctx \ + -p sealkeypass -i- <<< $secret -S enc_session.ctx + +-tpm2 sessionconfig enc_session.ctx --enable-encrypt ++tpm2 sessionconfig enc_session.ctx --enable-encrypt --disable-continuesession + unsealed=`tpm2 unseal -c seal_key.ctx -p sealkeypass -S enc_session.ctx` + test "$unsealed" == "$secret" + +-tpm2 flushcontext enc_session.ctx ++if [ -e enc_session.ctx ]; then ++ echo "enc_session.ctx was not deleted."; ++ exit 1 ++fi + + exit 0 +-- +2.45.2 + diff --git a/SOURCES/0002-tpm2_evictcontrol.c-Fix-segfault-for-output-of-handl.patch b/SOURCES/0002-tpm2_evictcontrol.c-Fix-segfault-for-output-of-handl.patch new file mode 100644 index 0000000..98ca9b6 --- /dev/null +++ b/SOURCES/0002-tpm2_evictcontrol.c-Fix-segfault-for-output-of-handl.patch @@ -0,0 +1,35 @@ +From 2be6ae25b564a7cf1c50404cd293e452c5a8f4a5 Mon Sep 17 00:00:00 2001 +From: Juergen Repp +Date: Thu, 23 May 2024 11:40:14 +0200 +Subject: [PATCH 2/8] tpm2_evictcontrol.c: Fix segfault for output of handle + ESYS_TR_NONE + +If the -o parameter was used when a persistent handle should be +evicted a segfault did occur. +Now the object is evicted an a warning is displayed. + +Signed-off-by: Juergen Repp +--- + tools/tpm2_evictcontrol.c | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +diff --git a/tools/tpm2_evictcontrol.c b/tools/tpm2_evictcontrol.c +index 8199be39..3fd7ee03 100644 +--- a/tools/tpm2_evictcontrol.c ++++ b/tools/tpm2_evictcontrol.c +@@ -190,7 +190,11 @@ static tool_rc tpm2_tool_onrun(ESYS_CONTEXT *ectx, tpm2_option_flags flags) { + tpm2_tool_output("action: %s\n", evicted ? "evicted" : "persisted"); + tool_rc tmp_rc = tool_rc_success; + if (ctx.output_arg) { +- tmp_rc = files_save_ESYS_TR(ectx, out_tr, ctx.output_arg); ++ if (out_tr == ESYS_TR_NONE) { ++ LOG_WARN("The parameter --output can't be used if a persistent object will be evicted"); ++ } else { ++ tmp_rc = files_save_ESYS_TR(ectx, out_tr, ctx.output_arg); ++ } + } + + if (!evicted) { +-- +2.49.0 + diff --git a/SOURCES/0002-tpm2_tool.c-Fix-missing-include-for-basename.patch b/SOURCES/0002-tpm2_tool.c-Fix-missing-include-for-basename.patch new file mode 100644 index 0000000..9605919 --- /dev/null +++ b/SOURCES/0002-tpm2_tool.c-Fix-missing-include-for-basename.patch @@ -0,0 +1,28 @@ +From 2e4d5da9a5e8808b1b075e0bde11c13fdd4c60b3 Mon Sep 17 00:00:00 2001 +From: Juergen Repp +Date: Tue, 19 Dec 2023 17:24:26 +0100 +Subject: [PATCH 2/6] tpm2_tool.c Fix missing include for basename. + +tpm2_tool.c did not compile without the include libgen.h on netbsd. +Fixes: #3321 + +Signed-off-by: Juergen Repp +--- + tools/tpm2_tool.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/tools/tpm2_tool.c b/tools/tpm2_tool.c +index edd04c83..f59e316a 100644 +--- a/tools/tpm2_tool.c ++++ b/tools/tpm2_tool.c +@@ -3,6 +3,7 @@ + #include + #include + #include ++#include + + #include + #include +-- +2.45.2 + diff --git a/SOURCES/0003-Fix-calloc-argument-order.patch b/SOURCES/0003-Fix-calloc-argument-order.patch new file mode 100644 index 0000000..c5f3862 --- /dev/null +++ b/SOURCES/0003-Fix-calloc-argument-order.patch @@ -0,0 +1,35 @@ +From a9ef4c986984cce821260f46d44d31fd88591c36 Mon Sep 17 00:00:00 2001 +From: dzil123 <5725958+dzil123@users.noreply.github.com> +Date: Tue, 4 Jun 2024 22:33:02 -0700 +Subject: [PATCH 3/8] Fix calloc argument order + +Signed-off-by: dzil123 <5725958+dzil123@users.noreply.github.com> +--- + lib/tpm2_openssl.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/lib/tpm2_openssl.c b/lib/tpm2_openssl.c +index ad43c8e1..79e80a5e 100644 +--- a/lib/tpm2_openssl.c ++++ b/lib/tpm2_openssl.c +@@ -422,7 +422,7 @@ static bool do_open_file(FILE *f, const char *path, char **pass) { + goto out; + } + +- char *tmp = calloc(sizeof(char), file_size + 1); ++ char *tmp = calloc(file_size + 1, sizeof(char)); + if (!tmp) { + LOG_ERR("oom"); + goto out; +@@ -477,7 +477,7 @@ static bool do_stdin(const char *passin, char **pass) { + + UNUSED(passin); + +- void *buf = calloc(sizeof(BYTE), UINT16_MAX + 1); ++ void *buf = calloc(UINT16_MAX + 1, sizeof(BYTE)); + if (!buf) { + LOG_ERR("oom"); + return false; +-- +2.49.0 + diff --git a/SOURCES/0003-tpm2_nvread-fix-input-handling-no-nv-index.patch b/SOURCES/0003-tpm2_nvread-fix-input-handling-no-nv-index.patch new file mode 100644 index 0000000..b352955 --- /dev/null +++ b/SOURCES/0003-tpm2_nvread-fix-input-handling-no-nv-index.patch @@ -0,0 +1,63 @@ +From 5b5dd6263f1f2d41f08abd60134396a12756c5e7 Mon Sep 17 00:00:00 2001 +From: Bill Roberts +Date: Sun, 10 Dec 2023 10:26:33 -0600 +Subject: [PATCH 3/6] tpm2_nvread: fix input handling no nv index + +Fixes: +./tools/tpm2 nvread +WARN: Reading full size of the NV index +ERROR: object string is empty +ERROR: Invalid handle authorization. +ERROR: Unable to run nvread + +with: +./tools/tpm2 nvread +ERROR: Must specify NV index argument +Usage: nvread [] +Where are: + [ -C | --hierarchy=] [ -o | --output=] [ -s | --size=] [ --offset=] + [ --cphash=] [ --rphash=] [ -n | --name=] [ -P | --auth=] + [ -S | --session=] [ --print-yaml] + +Signed-off-by: Bill Roberts +--- + tools/tpm2_nvread.c | 9 ++++++++- + 1 file changed, 8 insertions(+), 1 deletion(-) + +diff --git a/tools/tpm2_nvread.c b/tools/tpm2_nvread.c +index f64d00c1..8f9c61cc 100644 +--- a/tools/tpm2_nvread.c ++++ b/tools/tpm2_nvread.c +@@ -24,6 +24,7 @@ struct tpm_nvread_ctx { + TPM2B_NAME precalc_nvname; + UINT32 size_to_read; + UINT32 offset; ++ bool nv_specified; + + /* + * Outputs +@@ -192,6 +193,11 @@ static tool_rc check_options(tpm2_option_flags flags) { + return tool_rc_option_error; + } + ++ if(!ctx.nv_specified) { ++ LOG_ERR("Must specify NV index argument"); ++ return tool_rc_option_error; ++ } ++ + /* + * Peculiar to this and some other tools, the object (nvindex) name must + * be specified when only calculating the cpHash. +@@ -266,7 +272,8 @@ static bool on_arg(int argc, char **argv) { + if (!ctx.auth_hierarchy.ctx_path) { + ctx.auth_hierarchy.ctx_path = argv[0]; + } +- return on_arg_nv_index(argc, argv, &ctx.nv_index); ++ ++ return ctx.nv_specified = on_arg_nv_index(argc, argv, &ctx.nv_index); + } + + static bool on_option(char key, char *value) { +-- +2.45.2 + diff --git a/SOURCES/0004-tpm2_checkquote-Add-comparison-of-pcr-selection.patch b/SOURCES/0004-tpm2_checkquote-Add-comparison-of-pcr-selection.patch new file mode 100644 index 0000000..331fefc --- /dev/null +++ b/SOURCES/0004-tpm2_checkquote-Add-comparison-of-pcr-selection.patch @@ -0,0 +1,86 @@ +From 7076608db4b8a2cdcab6ff4bc47c23c935618e3b Mon Sep 17 00:00:00 2001 +From: Juergen Repp +Date: Tue, 5 Mar 2024 22:11:38 +0100 +Subject: [PATCH 4/6] tpm2_checkquote: Add comparison of pcr selection. + +The pcr selection which is passed with the --pcr parameter it not +compared with the attest. So it's possible to fake a valid +attestation. + +Fixes: CVE-2024-29039 + +Signed-off-by: Juergen Repp +Signed-off-by: Andreas Fuchs +--- + tools/misc/tpm2_checkquote.c | 41 +++++++++++++++++++++++++++++++++++- + 1 file changed, 40 insertions(+), 1 deletion(-) + +diff --git a/tools/misc/tpm2_checkquote.c b/tools/misc/tpm2_checkquote.c +index 6ce086f8..8a2a154e 100644 +--- a/tools/misc/tpm2_checkquote.c ++++ b/tools/misc/tpm2_checkquote.c +@@ -54,6 +54,37 @@ static tpm2_verifysig_ctx ctx = { + .pcr_hash = TPM2B_TYPE_INIT(TPM2B_DIGEST, buffer), + }; + ++static bool compare_pcr_selection(TPML_PCR_SELECTION *attest_sel, TPML_PCR_SELECTION *pcr_sel) { ++ if (attest_sel->count != pcr_sel->count) { ++ LOG_ERR("Selection sizes do not match."); ++ return false; ++ } ++ for (uint32_t i = 0; i < attest_sel->count; i++) { ++ for (uint32_t j = 0; j < pcr_sel->count; j++) { ++ if (attest_sel->pcrSelections[i].hash == ++ pcr_sel->pcrSelections[j].hash) { ++ if (attest_sel->pcrSelections[i].sizeofSelect != ++ pcr_sel->pcrSelections[j].sizeofSelect) { ++ LOG_ERR("Bitmask size does not match"); ++ return false; ++ } ++ if (memcmp(&attest_sel->pcrSelections[i].pcrSelect[0], ++ &pcr_sel->pcrSelections[j].pcrSelect[0], ++ attest_sel->pcrSelections[i].sizeofSelect) != 0) { ++ LOG_ERR("Selection bitmasks do not match"); ++ return false; ++ } ++ break; ++ } ++ if (j == pcr_sel->count - 1) { ++ LOG_ERR("Hash selections to not match."); ++ return false; ++ } ++ } ++ } ++ return true; ++} ++ + static bool verify(void) { + + bool result = false; +@@ -374,7 +405,7 @@ static tool_rc init(void) { + } + + TPM2B_ATTEST *msg = NULL; +- TPML_PCR_SELECTION pcr_select; ++ TPML_PCR_SELECTION pcr_select = { 0 }; + tpm2_pcrs *pcrs; + tpm2_pcrs temp_pcrs = {}; + tool_rc return_value = tool_rc_general_error; +@@ -537,6 +568,14 @@ static tool_rc init(void) { + goto err; + } + ++ if (ctx.flags.pcr) { ++ if (!compare_pcr_selection(&ctx.attest.attested.quote.pcrSelect, ++ &pcr_select)) { ++ LOG_ERR("PCR selection does not match PCR slection from attest!"); ++ goto err; ++ } ++ } ++ + // Figure out the digest for this message + res = tpm2_openssl_hash_compute_data(ctx.halg, msg->attestationData, + msg->size, &ctx.msg_hash); +-- +2.45.2 + diff --git a/SOURCES/0004-tpm2_createpolicy-flush-session-for-trial-policy.patch b/SOURCES/0004-tpm2_createpolicy-flush-session-for-trial-policy.patch new file mode 100644 index 0000000..adba763 --- /dev/null +++ b/SOURCES/0004-tpm2_createpolicy-flush-session-for-trial-policy.patch @@ -0,0 +1,63 @@ +From 596dc33f0093735254cd3dd086a8375fbf56fd47 Mon Sep 17 00:00:00 2001 +From: Juergen Repp +Date: Sat, 12 Oct 2024 12:04:15 +0200 +Subject: [PATCH 4/8] tpm2_createpolicy: flush session for trial policy. + +The created session is flushed if a trial policy is only used to compute +the policy digest. +Fixes: #3427 + +Signed-off-by: Juergen Repp +--- + tools/tpm2_createpolicy.c | 21 +++++++++++++++++---- + 1 file changed, 17 insertions(+), 4 deletions(-) + +diff --git a/tools/tpm2_createpolicy.c b/tools/tpm2_createpolicy.c +index b5686e05..48c039e8 100644 +--- a/tools/tpm2_createpolicy.c ++++ b/tools/tpm2_createpolicy.c +@@ -54,6 +54,9 @@ static create_policy_ctx pctx = { + + static tool_rc parse_policy_type_specific_command(ESYS_CONTEXT *ectx) { + ++ tool_rc rc; ++ TSS2_RC rval; ++ + if (!pctx.common_policy_options.policy_type.policy_pcr) { + LOG_ERR("Only PCR policy is currently supported!"); + return tool_rc_option_error; +@@ -71,7 +74,7 @@ static tool_rc parse_policy_type_specific_command(ESYS_CONTEXT *ectx) { + + tpm2_session **s = &pctx.common_policy_options.policy_session; + +- tool_rc rc = tpm2_session_open(ectx, session_data, s); ++ rc = tpm2_session_open(ectx, session_data, s); + if (rc != tool_rc_success) { + return rc; + } +@@ -91,9 +94,19 @@ static tool_rc parse_policy_type_specific_command(ESYS_CONTEXT *ectx) { + return rc; + } + +- return tpm2_policy_tool_finish(ectx, +- pctx.common_policy_options.policy_session, +- pctx.common_policy_options.policy_file); ++ rc = tpm2_policy_tool_finish(ectx, ++ pctx.common_policy_options.policy_session, ++ pctx.common_policy_options.policy_file); ++ if (rc != tool_rc_success) { ++ return rc; ++ } ++ if (pctx.common_policy_options.policy_session_type == TPM2_SE_TRIAL) { ++ rval = Esys_FlushContext(ectx, tpm2_session_get_handle(*s)); ++ if (rval != TPM2_RC_SUCCESS) { ++ return tool_rc_general_error; ++ } ++ } ++ return rc; + } + + static bool on_option(char key, char *value) { +-- +2.49.0 + diff --git a/SOURCES/0005-Support-high-range-NV-indexes-in-getekcert.patch b/SOURCES/0005-Support-high-range-NV-indexes-in-getekcert.patch new file mode 100644 index 0000000..4892a16 --- /dev/null +++ b/SOURCES/0005-Support-high-range-NV-indexes-in-getekcert.patch @@ -0,0 +1,275 @@ +From a7468cf7deaf5cf608da32923b5797cdb497cde1 Mon Sep 17 00:00:00 2001 +From: "loic.sikidi" +Date: Mon, 9 Dec 2024 23:47:25 +0100 +Subject: [PATCH 5/8] Support high range NV indexes in getekcert + +Signed-off-by: loic.sikidi +--- + test/integration/tests/getekcertificate.sh | 38 ++++++ + tools/tpm2_getekcertificate.c | 141 +++++++++++++++++++-- + 2 files changed, 168 insertions(+), 11 deletions(-) + +diff --git a/test/integration/tests/getekcertificate.sh b/test/integration/tests/getekcertificate.sh +index 96e92cc0..14c32c2d 100644 +--- a/test/integration/tests/getekcertificate.sh ++++ b/test/integration/tests/getekcertificate.sh +@@ -80,6 +80,8 @@ diff test_ecc_ek.pem test_ek.pem + # Retrieve EK certificates from NV indices + RSA_EK_CERT_NV_INDEX=0x01C00002 + ECC_EK_CERT_NV_INDEX=0x01C0000A ++RSA_3072_EK_CERT_NV_INDEX=0x01C0001C ++ECC_NIST_P384_EK_CERT_NV_INDEX=0x01C00016 + + define_ek_cert_nv_index() { + file_size=`ls -l $1 | awk {'print $5'}` +@@ -120,4 +122,40 @@ tpm2 getekcertificate -o nv_rsa_ek_cert.der -o nv_ecc_ek_cert.der + diff nv_rsa_ek_cert.der rsa_ek_cert.der + diff nv_ecc_ek_cert.der ecc_ek_cert.der + ++rm nv_rsa_ek_cert.der rsa_ek_cert.der nv_ecc_ek_cert.der ecc_ek_cert.der -f ++ ++## RSA & ECC self-signed EK certs stored in high range NV indexes ++tpm2 nvundefine -C p $RSA_EK_CERT_NV_INDEX ++tpm2 nvundefine -C p $ECC_EK_CERT_NV_INDEX ++ ++create_self_signed_ek_cert(){ ++ case "$1" in ++ *rsa_3072) ++ openssl genpkey -algorithm RSA -out priv_key.pem \ ++ -pkeyopt rsa_keygen_bits:3072 > /dev/null 2>&1 ++ openssl req -new -key priv_key.pem -x509 -days 1 \ ++ -subj "/" -outform DER -out $2 ++ ;; ++ *ecc_nist_p384) ++ openssl ecparam -name secp384r1 -genkey -out priv_key.pem > /dev/null 2>&1 ++ openssl req -new -key priv_key.pem -x509 -days 1 \ ++ -subj "/" -outform DER -out $2 ++ ;; ++ *) echo "Unsupported key type $1"; return 1;; ++ esac ++} ++ ++create_self_signed_ek_cert rsa_3072 rsa_ek_cert.der ++create_self_signed_ek_cert ecc_nist_p384 ecc_ek_cert.der ++ ++define_ek_cert_nv_index rsa_ek_cert.der $RSA_3072_EK_CERT_NV_INDEX ++define_ek_cert_nv_index ecc_ek_cert.der $ECC_NIST_P384_EK_CERT_NV_INDEX ++ ++tpm2 getekcertificate -o nv_rsa_ek_cert.der -o nv_ecc_ek_cert.der ++ ++diff nv_rsa_ek_cert.der rsa_ek_cert.der ++diff nv_ecc_ek_cert.der ecc_ek_cert.der ++ ++rm nv_rsa_ek_cert.der rsa_ek_cert.der nv_ecc_ek_cert.der ecc_ek_cert.der priv_key.pem -f ++ + exit 0 +diff --git a/tools/tpm2_getekcertificate.c b/tools/tpm2_getekcertificate.c +index f0d1ca36..3c9bddeb 100644 +--- a/tools/tpm2_getekcertificate.c ++++ b/tools/tpm2_getekcertificate.c +@@ -20,6 +20,71 @@ + #include "tpm2_nv_util.h" + #include "tpm2_tool.h" + ++ ++/* ++ * Sourced from TCG Vendor ID Registry v1.06: ++ * https://trustedcomputinggroup.org/resource/vendor-id-registry/ ++ * ++ */ ++ ++typedef enum tpm_manufacturer tpm_manufacturer; ++enum tpm_manufacturer { ++ VENDOR_AMD = 0x414D4400, ++ VENDOR_ATMEL = 0x41544D4C, ++ VENDOR_BROADCOM = 0x4252434D, ++ VENDOR_CISCO = 0x4353434F, ++ VENDOR_FLYSLICE = 0x464C5953, ++ VENDOR_ROCKCHIP = 0x524F4343, ++ VENDOR_GOOGLE = 0x474F4F47, ++ VENDOR_HPE = 0x48504500, ++ VENDOR_HUAWEI = 0x48495349, ++ VENDOR_IBM = 0x49424D00, ++ VENDOR_IBMSIM = 0x49424D20, // Used only by mssim/ibmswtpm2 ++ VENDOR_INFINEON = 0x49465800, ++ VENDOR_INTEL = 0x494E5443, ++ VENDOR_LENOVO = 0x4C454E00, ++ VENDOR_MICROSOFT = 0x4D534654, ++ VENDOR_NSM = 0x4E534D20, ++ VENDOR_NATIONZ = 0x4E545A00, ++ VENDOR_NUVOTON = 0x4E544300, ++ VENDOR_QUALCOMM = 0x51434F4D, ++ VENDOR_SAMSUNG = 0x534D534E, ++ VENDOR_SINOSUN = 0x534E5300, ++ VENDOR_SMSC = 0x534D5343, ++ VENDOR_STM = 0x53544D20, ++ VENDOR_TXN = 0x54584E00, ++ VENDOR_WINBOND = 0x57454300, ++}; ++ ++typedef enum pubkey_enc_mode pubkey_enc_mode; ++enum pubkey_enc_mode { ++ ENC_AUTO = 0, ++ ENC_INTEL = 1, ++ ENC_AMD = 2, ++}; ++ ++/* ++ * Sourced from TCG PC Client Platform TPM Profile Specification v1.05 rev 14: ++ * https://trustedcomputinggroup.org/resource/pc-client-platform-tpm-profile-ptp-specification/ ++ * ++ */ ++ ++typedef enum ek_nv_index ek_nv_index; ++enum ek_nv_index { ++ RSA_EK_CERT_NV_INDEX = 0x01C00002, ++ ECC_EK_CERT_NV_INDEX = 0x01C0000A, ++ RSA_2048_EK_CERT_NV_INDEX = 0x01C00012, ++ RSA_3072_EK_CERT_NV_INDEX = 0x01C0001C, ++ RSA_4096_EK_CERT_NV_INDEX = 0x01C0001E, ++ ECC_NIST_P256_EK_CERT_NV_INDEX = 0x01C00014, ++ ECC_NIST_P384_EK_CERT_NV_INDEX = 0x01C00016, ++ ECC_NIST_P521_EK_CERT_NV_INDEX = 0x01C00018, ++ ECC_SM2_P256_EK_CERT_NV_INDEX = 0x01C0001A, ++}; ++ ++#define EK_SERVER_INTEL "https://ekop.intel.com/ekcertservice/" ++#define EK_SERVER_AMD "https://ftpm.amd.com/pki/aia/" ++ + typedef struct tpm_getekcertificate_ctx tpm_getekcertificate_ctx; + struct tpm_getekcertificate_ctx { + // TPM Device properties +@@ -28,6 +93,8 @@ struct tpm_getekcertificate_ctx { + bool is_intc_cert; + bool is_rsa_ek_cert_nv_location_defined; + bool is_ecc_ek_cert_nv_location_defined; ++ ek_nv_index rsa_ek_cert_nv_location; ++ ek_nv_index ecc_ek_cert_nv_location; + bool is_tpmgeneratedeps; + // Certficate data handling + uint8_t cert_count; +@@ -55,6 +122,46 @@ static tpm_getekcertificate_ctx ctx = { + .cert_count = 0, + }; + ++ ++typedef enum key_type key_type; ++enum key_type { ++ KTYPE_RSA = 0, ++ KTYPE_ECC = 1, ++}; ++ ++typedef struct ek_index_map ek_index_map; ++struct ek_index_map ++{ ++ const char *name; ++ key_type key_type; ++ ek_nv_index index; ++ TPMI_ALG_HASH hash_alg; ++}; ++ ++static ek_index_map ek_index_maps[] = { ++ {"rsa", KTYPE_RSA, RSA_EK_CERT_NV_INDEX, TPM2_ALG_SHA256}, ++ {"rsa2048", KTYPE_RSA, RSA_2048_EK_CERT_NV_INDEX, TPM2_ALG_SHA256}, ++ {"rsa3072", KTYPE_RSA, RSA_3072_EK_CERT_NV_INDEX, TPM2_ALG_SHA384}, ++ {"rsa4096", KTYPE_RSA, RSA_4096_EK_CERT_NV_INDEX, TPM2_ALG_SHA512}, ++ {"ecc", KTYPE_ECC, ECC_EK_CERT_NV_INDEX, TPM2_ALG_SHA256}, ++ {"ecc_nist_p256", KTYPE_ECC, ECC_NIST_P256_EK_CERT_NV_INDEX, TPM2_ALG_SHA256}, ++ {"ecc_nist_p384", KTYPE_ECC, ECC_NIST_P384_EK_CERT_NV_INDEX, TPM2_ALG_SHA384}, ++ {"ecc_nist_p521", KTYPE_ECC, ECC_NIST_P521_EK_CERT_NV_INDEX, TPM2_ALG_SHA512}, ++ {"ecc_sm2_p256", KTYPE_ECC, ECC_SM2_P256_EK_CERT_NV_INDEX, TPM2_ALG_SM3_256}, ++}; ++ ++static const ek_index_map *lookup_ek_index_map(const TPMI_RH_NV_INDEX index) { ++ size_t i; ++ ++ for (i = 0; i < ARRAY_LEN(ek_index_maps); i++) ++ { ++ if (index == ek_index_maps[i].index) { ++ return &ek_index_maps[i]; ++ } ++ } ++ return NULL; ++} ++ + static unsigned char *hash_ek_public(void) { + + unsigned char *hash = (unsigned char*) malloc(SHA256_DIGEST_LENGTH); +@@ -387,11 +494,20 @@ tool_rc get_tpm_properties(ESYS_CONTEXT *ectx) { + UINT32 i; + for (i = 0; i < capability_data->data.handles.count; i++) { + TPMI_RH_NV_INDEX index = capability_data->data.handles.handle[i]; +- if (index == RSA_EK_CERT_NV_INDEX) { ++ const ek_index_map *m = lookup_ek_index_map(index); ++ if (!m) { ++ continue; ++ } ++ ++ if (m->key_type == KTYPE_RSA) { ++ LOG_INFO("Found pre-provisioned RSA EK certificate at %u [type=%s]", index, m->name); + ctx.is_rsa_ek_cert_nv_location_defined = true; ++ ctx.rsa_ek_cert_nv_location = m->index; + } +- if (index == ECC_EK_CERT_NV_INDEX) { ++ if (m->key_type == KTYPE_ECC) { ++ LOG_INFO("Found pre-provisioned ECC EK certificate at %u [type=%s]", index, m->name); + ctx.is_ecc_ek_cert_nv_location_defined = true; ++ ctx.ecc_ek_cert_nv_location = m->index; + } + } + +@@ -412,12 +528,15 @@ static tool_rc nv_read(ESYS_CONTEXT *ectx, TPMI_RH_NV_INDEX nv_index) { + * with attributes: + * ppwrite|ppread|ownerread|authread|no_da|written|platformcreate + */ +- char index_string[11]; +- if (nv_index == RSA_EK_CERT_NV_INDEX) { +- strcpy(index_string, "0x01C00002"); +- } else { +- strcpy(index_string, "0x01C0000A"); ++ const ek_index_map *m = lookup_ek_index_map(nv_index); ++ if (!m) { ++ LOG_ERR("Unsupported NV INDEX, got \"%u\"", nv_index); ++ return tool_rc_unsupported; + } ++ ++ const bool is_rsa = m->key_type == KTYPE_RSA; ++ char index_string[11]; ++ snprintf(index_string, sizeof(index_string), "%u", m->index); + tpm2_loaded_object object; + tool_rc tmp_rc = tool_rc_success; + tool_rc rc = tpm2_util_object_load_auth(ectx, index_string, NULL, &object, +@@ -431,11 +550,11 @@ static tool_rc nv_read(ESYS_CONTEXT *ectx, TPMI_RH_NV_INDEX nv_index) { + rc = nv_index == RSA_EK_CERT_NV_INDEX ? + + tpm2_util_nv_read(ectx, nv_index, 0, 0, &object, &ctx.rsa_cert_buffer, +- &ctx.rsa_cert_buffer_size, &cp_hash, &rp_hash, TPM2_ALG_SHA256, 0, ++ &ctx.rsa_cert_buffer_size, &cp_hash, &rp_hash, m->hash_alg, 0, + ESYS_TR_NONE, ESYS_TR_NONE) : + + tpm2_util_nv_read(ectx, nv_index, 0, 0, &object, &ctx.ecc_cert_buffer, +- &ctx.ecc_cert_buffer_size, &cp_hash, &rp_hash, TPM2_ALG_SHA256, 0, ++ &ctx.ecc_cert_buffer_size, &cp_hash, &rp_hash, m->hash_alg, 0, + ESYS_TR_NONE, ESYS_TR_NONE); + + nv_read_out: +@@ -475,14 +594,14 @@ static tool_rc get_nv_ek_certificate(ESYS_CONTEXT *ectx) { + + tool_rc rc = tool_rc_success; + if (ctx.is_rsa_ek_cert_nv_location_defined) { +- rc = nv_read(ectx, RSA_EK_CERT_NV_INDEX); ++ rc = nv_read(ectx, ctx.rsa_ek_cert_nv_location); + if (rc != tool_rc_success) { + return rc; + } + } + + if (ctx.is_ecc_ek_cert_nv_location_defined) { +- rc = nv_read(ectx, ECC_EK_CERT_NV_INDEX); ++ rc = nv_read(ectx, ctx.ecc_ek_cert_nv_location); + } + + return rc; +-- +2.49.0 + diff --git a/SOURCES/0005-tpm2_checkquote-Fix-check-of-magic-number.patch b/SOURCES/0005-tpm2_checkquote-Fix-check-of-magic-number.patch new file mode 100644 index 0000000..f7c8c74 --- /dev/null +++ b/SOURCES/0005-tpm2_checkquote-Fix-check-of-magic-number.patch @@ -0,0 +1,38 @@ +From 0f122ba3f7bdee12f8ee725db41d90e737fb3e49 Mon Sep 17 00:00:00 2001 +From: Juergen Repp +Date: Tue, 31 Oct 2023 11:29:50 +0100 +Subject: [PATCH 5/6] tpm2_checkquote: Fix check of magic number. + +It was not checked whether the magic number in the +attest is equal to TPM2_GENERATED_VALUE. +So an malicious attacker could generate arbitrary quote data +which was not detected by tpm2 checkquote. + +Fixes: CVE-2024-29038 + +Signed-off-by: Juergen Repp +--- + tools/misc/tpm2_checkquote.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +diff --git a/tools/misc/tpm2_checkquote.c b/tools/misc/tpm2_checkquote.c +index 8a2a154e..5083d855 100644 +--- a/tools/misc/tpm2_checkquote.c ++++ b/tools/misc/tpm2_checkquote.c +@@ -146,6 +146,13 @@ static bool verify(void) { + goto err; + } + ++ // check magic ++ if (ctx.attest.magic != TPM2_GENERATED_VALUE) { ++ LOG_ERR("Bad magic, got: 0x%x, expected: 0x%x", ++ ctx.attest.magic, TPM2_GENERATED_VALUE); ++ return false; ++ } ++ + // Also ensure digest from quote matches PCR digest + if (ctx.flags.pcr) { + if (!tpm2_util_verify_digests(&ctx.attest.attested.quote.pcrDigest, +-- +2.45.2 + diff --git a/SOURCES/0006-tpm2_getrandom-Fix-force-parameter.patch b/SOURCES/0006-tpm2_getrandom-Fix-force-parameter.patch new file mode 100644 index 0000000..342965a --- /dev/null +++ b/SOURCES/0006-tpm2_getrandom-Fix-force-parameter.patch @@ -0,0 +1,29 @@ +From 97960847562fb6350f4b8a8807f169ce37ea2864 Mon Sep 17 00:00:00 2001 +From: Juergen Repp +Date: Thu, 16 Jan 2025 11:15:56 +0100 +Subject: [PATCH 6/8] tpm2_getrandom: Fix --force parameter + +The --force parameter did require an argument but was always set +to true if used. Now no_argument is used in the option table. + +Signed-off-by: Juergen Repp +--- + tools/tpm2_getrandom.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/tools/tpm2_getrandom.c b/tools/tpm2_getrandom.c +index edfc0068..f4b064d9 100644 +--- a/tools/tpm2_getrandom.c ++++ b/tools/tpm2_getrandom.c +@@ -323,7 +323,7 @@ static bool tpm2_tool_onstart(tpm2_options **opts) { + + const struct option topts[] = { + { "output", required_argument, NULL, 'o' }, +- { "force", required_argument, NULL, 'f' }, ++ { "force", no_argument, NULL, 'f' }, + { "hex", no_argument, NULL, 0 }, + { "session", required_argument, NULL, 'S' }, + { "cphash", required_argument, NULL, 1 }, +-- +2.49.0 + diff --git a/SOURCES/0006-tpm2_setprimarypolicy-Fix-resource-leak.patch b/SOURCES/0006-tpm2_setprimarypolicy-Fix-resource-leak.patch new file mode 100644 index 0000000..945fedc --- /dev/null +++ b/SOURCES/0006-tpm2_setprimarypolicy-Fix-resource-leak.patch @@ -0,0 +1,28 @@ +From d7c541d839d6c470fbd273d0c482091a1fe59fe6 Mon Sep 17 00:00:00 2001 +From: rpm-build +Date: Tue, 18 Jun 2024 15:42:13 +0200 +Subject: [PATCH 6/6] tpm2_setprimarypolicy: Fix resource leak +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Signed-off-by: Štěpán Horáček +--- + tools/tpm2_setprimarypolicy.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/tools/tpm2_setprimarypolicy.c b/tools/tpm2_setprimarypolicy.c +index 140a8083..459d3d03 100644 +--- a/tools/tpm2_setprimarypolicy.c ++++ b/tools/tpm2_setprimarypolicy.c +@@ -134,6 +134,7 @@ static tool_rc process_setprimarypolicy_input(ESYS_CONTEXT *ectx, + (*auth_policy)->buffer, &((*auth_policy)->size)); + if (!result) { + LOG_ERR("Failed loading policy digest from path"); ++ free(*auth_policy); + return tool_rc_general_error; + } + } +-- +2.45.2 + diff --git a/SOURCES/0007-tpm2_eventlog_yaml.c-Fix-output-of-BlobDescription.patch b/SOURCES/0007-tpm2_eventlog_yaml.c-Fix-output-of-BlobDescription.patch new file mode 100644 index 0000000..e77f22c --- /dev/null +++ b/SOURCES/0007-tpm2_eventlog_yaml.c-Fix-output-of-BlobDescription.patch @@ -0,0 +1,30 @@ +From 8dbb135c14392e61111a4dfcceffe990148b68fd Mon Sep 17 00:00:00 2001 +From: Juergen Repp +Date: Sat, 8 Feb 2025 19:59:01 +0100 +Subject: [PATCH 7/8] tpm2_eventlog_yaml.c Fix output of BlobDescription. + +The last byte of the BlobDescription for an EV_EFI_PLATFORM_FIRMWARE_BLOB2 +event was not displayed. +Fixes: #3455. + +Signed-off-by: Juergen Repp +--- + lib/tpm2_eventlog_yaml.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/lib/tpm2_eventlog_yaml.c b/lib/tpm2_eventlog_yaml.c +index 59a5d8fc..343fb658 100644 +--- a/lib/tpm2_eventlog_yaml.c ++++ b/lib/tpm2_eventlog_yaml.c +@@ -582,7 +582,7 @@ bool yaml_uefi_platfwblob2(UEFI_PLATFORM_FIRMWARE_BLOB2 *data) { + return false; + } + +- bytes_to_str (data->BlobDescription, blobdescsize, eventdesc, 2*blobdescsize); ++ bytes_to_str (data->BlobDescription, blobdescsize, eventdesc, 2*blobdescsize + 1); + + tpm2_tool_output(" Event:\n" + " BlobDescriptionSize: %d\n" +-- +2.49.0 + diff --git a/SOURCES/0008-tpm2_encode-Fix-setting-emptyAuth-in-generated-pem-f.patch b/SOURCES/0008-tpm2_encode-Fix-setting-emptyAuth-in-generated-pem-f.patch new file mode 100644 index 0000000..28e1528 --- /dev/null +++ b/SOURCES/0008-tpm2_encode-Fix-setting-emptyAuth-in-generated-pem-f.patch @@ -0,0 +1,30 @@ +From e20f7a0bb6febb61d9f82430e27a4ce4aed64399 Mon Sep 17 00:00:00 2001 +From: Juergen Repp +Date: Mon, 17 Feb 2025 18:04:49 +0100 +Subject: [PATCH 8/8] tpm2_encode: Fix setting emptyAuth in generated pem file. + +emptyAuth was set to 1 if an auth value for the input key was +used and to 0 if an auth value was used. +Fixes: #3458 + +Signed-off-by: Juergen Repp +--- + tools/misc/tpm2_encodeobject.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/tools/misc/tpm2_encodeobject.c b/tools/misc/tpm2_encodeobject.c +index 80de14f5..74675b06 100644 +--- a/tools/misc/tpm2_encodeobject.c ++++ b/tools/misc/tpm2_encodeobject.c +@@ -195,7 +195,7 @@ encode(void) + goto error; + } + +- tpk->emptyAuth = ctx.object.needs_auth; ++ tpk->emptyAuth = !ctx.object.needs_auth; + + if ((ctx.parent.object.handle >> TPM2_HR_SHIFT) == TPM2_HT_PERSISTENT) { + ASN1_INTEGER_set(tpk->parent, ctx.parent.object.handle); +-- +2.49.0 + diff --git a/SOURCES/576a31bcc910da517067b29667f45fbe78e812e0.patch b/SOURCES/576a31bcc910da517067b29667f45fbe78e812e0.patch new file mode 100644 index 0000000..0ba4e6a --- /dev/null +++ b/SOURCES/576a31bcc910da517067b29667f45fbe78e812e0.patch @@ -0,0 +1,194 @@ +From 576a31bcc910da517067b29667f45fbe78e812e0 Mon Sep 17 00:00:00 2001 +From: Thore Sommer +Date: Tue, 25 Apr 2023 17:24:55 +0300 +Subject: [PATCH] tpm2_eventlog: add support for replay with different + StartupLocality + +According to the "TCG PC Client Platform Firmware Profile Specification +Level 00 Version 1.05 Revision 23" section 10.4.5.3 the startup locality +is the starting value of PCR0. This can be currently either 0 or 3. + +Signed-off-by: Thore Sommer +--- + lib/efi_event.h | 1 + + lib/tpm2_eventlog.c | 31 ++++++++++++++++++++++++++++--- + lib/tpm2_eventlog.h | 2 +- + test/unit/test_tpm2_eventlog.c | 14 +++++++------- + 4 files changed, 37 insertions(+), 11 deletions(-) + +diff --git a/lib/efi_event.h b/lib/efi_event.h +index cc2ffc983..e1b295501 100644 +--- a/lib/efi_event.h ++++ b/lib/efi_event.h +@@ -45,6 +45,7 @@ + #define EV_EFI_HANDOFF_TABLES2 EV_EFI_EVENT_BASE + 0xb + #define EV_EFI_VARIABLE_BOOT2 EV_EFI_EVENT_BASE + 0xc + ++#define EV_EFI_HCRTM_EVENT EV_EFI_EVENT_BASE + 0x10 + #define EV_EFI_VARIABLE_AUTHORITY EV_EFI_EVENT_BASE + 0xe0 + + #ifndef PACKED +diff --git a/lib/tpm2_eventlog.c b/lib/tpm2_eventlog.c +index e2e27f02b..2514b524e 100644 +--- a/lib/tpm2_eventlog.c ++++ b/lib/tpm2_eventlog.c +@@ -31,7 +31,7 @@ bool digest2_accumulator_callback(TCG_DIGEST2 const *digest, size_t size, + * 'size' parameter. + */ + bool foreach_digest2(tpm2_eventlog_context *ctx, UINT32 eventType, unsigned pcr_index, +- TCG_DIGEST2 const *digest, size_t count, size_t size) { ++ TCG_DIGEST2 const *digest, size_t count, size_t size, uint8_t locality) { + + if (digest == NULL) { + LOG_ERR("digest cannot be NULL"); +@@ -81,6 +81,10 @@ bool foreach_digest2(tpm2_eventlog_context *ctx, UINT32 eventType, unsigned pcr_ + LOG_WARN("PCR%d algorithm %d unsupported", pcr_index, alg); + } + ++ if (eventType == EV_NO_ACTION && pcr && pcr_index == 0 && locality > 0 ){ ++ pcr[alg_size -1] = locality; ++ } ++ + if (eventType != EV_NO_ACTION && pcr && + !tpm2_openssl_pcr_extend(alg, pcr, digest->Digest, alg_size)) { + LOG_ERR("PCR%d extend failed", pcr_index); +@@ -184,7 +188,7 @@ bool parse_event2(TCG_EVENT_HEADER2 const *eventhdr, size_t buf_size, + ret = foreach_digest2(&ctx, eventhdr->EventType, + eventhdr->PCRIndex, + eventhdr->Digests, eventhdr->DigestCount, +- buf_size - sizeof(*eventhdr)); ++ buf_size - sizeof(*eventhdr), 0); + if (ret != true) { + return false; + } +@@ -430,6 +434,7 @@ bool foreach_event2(tpm2_eventlog_context *ctx, TCG_EVENT_HEADER2 const *eventhd + TCG_EVENT_HEADER2 const *eventhdr; + size_t event_size; + bool ret; ++ bool found_hcrtm = false; + + for (eventhdr = eventhdr_start, event_size = 0; + size > 0; +@@ -437,6 +442,7 @@ bool foreach_event2(tpm2_eventlog_context *ctx, TCG_EVENT_HEADER2 const *eventhd + size -= event_size) { + + size_t digests_size = 0; ++ uint8_t locality = 0; + + ret = parse_event2(eventhdr, size, &event_size, &digests_size); + if (!ret) { +@@ -445,6 +451,25 @@ bool foreach_event2(tpm2_eventlog_context *ctx, TCG_EVENT_HEADER2 const *eventhd + + TCG_EVENT2 *event = (TCG_EVENT2*)((uintptr_t)eventhdr->Digests + digests_size); + ++ if (eventhdr->EventType == EV_EFI_HCRTM_EVENT && eventhdr->PCRIndex == 0) { ++ found_hcrtm = true; ++ } ++ ++ /* Handle StartupLocality in replay for PCR0 */ ++ if (!found_hcrtm && eventhdr->EventType == EV_NO_ACTION && eventhdr->PCRIndex == 0) { ++ if (event_size < sizeof(EV_NO_ACTION_STRUCT)){ ++ LOG_ERR("EventSize is too small\n"); ++ return false; ++ } ++ ++ EV_NO_ACTION_STRUCT *locality_event = (EV_NO_ACTION_STRUCT*)event->Event; ++ ++ if (memcmp(locality_event->Signature, STARTUP_LOCALITY_SIGNATURE, sizeof(STARTUP_LOCALITY_SIGNATURE)) == 0){ ++ locality = locality_event->Cases.StartupLocality; ++ } ++ } ++ ++ + /* event header callback */ + if (ctx->event2hdr_cb != NULL) { + ret = ctx->event2hdr_cb(eventhdr, event_size, ctx->data); +@@ -455,7 +480,7 @@ bool foreach_event2(tpm2_eventlog_context *ctx, TCG_EVENT_HEADER2 const *eventhd + + /* digest callback foreach digest */ + ret = foreach_digest2(ctx, eventhdr->EventType, eventhdr->PCRIndex, +- eventhdr->Digests, eventhdr->DigestCount, digests_size); ++ eventhdr->Digests, eventhdr->DigestCount, digests_size, locality); + if (ret != true) { + return false; + } +diff --git a/lib/tpm2_eventlog.h b/lib/tpm2_eventlog.h +index f141e8068..0af897070 100644 +--- a/lib/tpm2_eventlog.h ++++ b/lib/tpm2_eventlog.h +@@ -45,7 +45,7 @@ bool digest2_accumulator_callback(TCG_DIGEST2 const *digest, size_t size, + + bool parse_event2body(TCG_EVENT2 const *event, UINT32 type); + bool foreach_digest2(tpm2_eventlog_context *ctx, UINT32 eventType, unsigned pcr_index, +- TCG_DIGEST2 const *event_hdr, size_t count, size_t size); ++ TCG_DIGEST2 const *event_hdr, size_t count, size_t size, uint8_t locality); + bool parse_event2(TCG_EVENT_HEADER2 const *eventhdr, size_t buf_size, + size_t *event_size, size_t *digests_size); + bool foreach_event2(tpm2_eventlog_context *ctx, TCG_EVENT_HEADER2 const *eventhdr_start, size_t size); +diff --git a/test/unit/test_tpm2_eventlog.c b/test/unit/test_tpm2_eventlog.c +index e48404d8d..1c36f907e 100644 +--- a/test/unit/test_tpm2_eventlog.c ++++ b/test/unit/test_tpm2_eventlog.c +@@ -27,7 +27,7 @@ static void test_foreach_digest2_null(void **state){ + (void)state; + tpm2_eventlog_context ctx = {0}; + +- assert_false(foreach_digest2(&ctx, 0, 0, NULL, 0, sizeof(TCG_DIGEST2))); ++ assert_false(foreach_digest2(&ctx, 0, 0, NULL, 0, sizeof(TCG_DIGEST2), 0)); + } + static void test_foreach_digest2_size(void **state) { + +@@ -36,7 +36,7 @@ static void test_foreach_digest2_size(void **state) { + TCG_DIGEST2 *digest = (TCG_DIGEST2*)buf; + tpm2_eventlog_context ctx = { .digest2_cb = foreach_digest2_test_callback }; + +- assert_false(foreach_digest2(&ctx, 0, 0, digest, 1, sizeof(TCG_DIGEST2) - 1)); ++ assert_false(foreach_digest2(&ctx, 0, 0, digest, 1, sizeof(TCG_DIGEST2) - 1, 0)); + } + static void test_foreach_digest2(void **state) { + +@@ -47,7 +47,7 @@ static void test_foreach_digest2(void **state) { + will_return(foreach_digest2_test_callback, true); + + tpm2_eventlog_context ctx = { .digest2_cb = foreach_digest2_test_callback }; +- assert_true(foreach_digest2(&ctx, 0, 0, digest, 1, TCG_DIGEST2_SHA1_SIZE)); ++ assert_true(foreach_digest2(&ctx, 0, 0, digest, 1, TCG_DIGEST2_SHA1_SIZE, 0)); + } + static void test_foreach_digest2_cbnull(void **state){ + +@@ -56,7 +56,7 @@ static void test_foreach_digest2_cbnull(void **state){ + TCG_DIGEST2* digest = (TCG_DIGEST2*)buf; + + tpm2_eventlog_context ctx = {0}; +- assert_true(foreach_digest2(&ctx, 0, 0, digest, 1, TCG_DIGEST2_SHA1_SIZE)); ++ assert_true(foreach_digest2(&ctx, 0, 0, digest, 1, TCG_DIGEST2_SHA1_SIZE, 0)); + } + static void test_sha1(void **state){ + +@@ -73,7 +73,7 @@ static void test_sha1(void **state){ + memcpy(digest->Digest, "the magic words are:", TPM2_SHA1_DIGEST_SIZE); + + tpm2_eventlog_context ctx = {0}; +- assert_true(foreach_digest2(&ctx, 0, pcr_index, digest, 1, TCG_DIGEST2_SHA1_SIZE)); ++ assert_true(foreach_digest2(&ctx, 0, pcr_index, digest, 1, TCG_DIGEST2_SHA1_SIZE, 0)); + assert_memory_equal(ctx.sha1_pcrs[pcr_index], sha1sum, sizeof(sha1sum)); + } + static void test_sha256(void **state){ +@@ -93,7 +93,7 @@ static void test_sha256(void **state){ + memcpy(digest->Digest, "The Magic Words are Squeamish Ossifrage, for RSA-129 (from 1977)", TPM2_SHA256_DIGEST_SIZE); + + tpm2_eventlog_context ctx = {0}; +- assert_true(foreach_digest2(&ctx, 0, pcr_index, digest, 1, TCG_DIGEST2_SHA256_SIZE)); ++ assert_true(foreach_digest2(&ctx, 0, pcr_index, digest, 1, TCG_DIGEST2_SHA256_SIZE, 0)); + assert_memory_equal(ctx.sha256_pcrs[pcr_index], sha256sum, sizeof(sha256sum)); + } + static void test_foreach_digest2_cbfail(void **state){ +@@ -105,7 +105,7 @@ static void test_foreach_digest2_cbfail(void **state){ + will_return(foreach_digest2_test_callback, false); + + tpm2_eventlog_context ctx = { .digest2_cb = foreach_digest2_test_callback }; +- assert_false(foreach_digest2(&ctx, 0, 0, digest, 1, TCG_DIGEST2_SHA1_SIZE)); ++ assert_false(foreach_digest2(&ctx, 0, 0, digest, 1, TCG_DIGEST2_SHA1_SIZE, 0)); + } + static void test_digest2_accumulator_callback(void **state) { + diff --git a/SPECS/tpm2-tools.spec b/SPECS/tpm2-tools.spec index 837b621..a01804c 100644 --- a/SPECS/tpm2-tools.spec +++ b/SPECS/tpm2-tools.spec @@ -2,7 +2,7 @@ Name: tpm2-tools Version: 5.2 -Release: 3%{?candidate:.%{candidate}}%{?dist} +Release: 6%{?candidate:.%{candidate}}%{?dist} Summary: A bunch of TPM testing toolS build upon tpm2-tss License: BSD @@ -38,6 +38,22 @@ Patch115: 0015-tpm-errata-switch-to-twos-complement.patch Patch116: 0016-tpm2_eventlog.c-Fix-pcr-extension-for-EV_NO_ACTION.patch Patch117: 0017-kdfa.c-Fix-problem-with-FORTIFY_SOURCE-on-Fedora.patch Patch118: add_pregenerated_doc.patch +Patch201: 0001-tpm2_sessionconfig-fix-usage-of-disable-continuesess.patch +Patch202: 0002-tpm2_tool.c-Fix-missing-include-for-basename.patch +Patch203: 0003-tpm2_nvread-fix-input-handling-no-nv-index.patch +Patch204: 0004-tpm2_checkquote-Add-comparison-of-pcr-selection.patch +Patch205: 0005-tpm2_checkquote-Fix-check-of-magic-number.patch +Patch206: 0006-tpm2_setprimarypolicy-Fix-resource-leak.patch +# tpm2_eventlog: add support for replay with different StartupLocality +Patch207: %{url}/commit/576a31bcc910da517067b29667f45fbe78e812e0.patch +Patch301: 0001-Fix-handling-of-testResult-in-tpm2_gettestresult.patch +Patch302: 0002-tpm2_evictcontrol.c-Fix-segfault-for-output-of-handl.patch +Patch303: 0003-Fix-calloc-argument-order.patch +Patch304: 0004-tpm2_createpolicy-flush-session-for-trial-policy.patch +Patch305: 0005-Support-high-range-NV-indexes-in-getekcert.patch +Patch306: 0006-tpm2_getrandom-Fix-force-parameter.patch +Patch307: 0007-tpm2_eventlog_yaml.c-Fix-output-of-BlobDescription.patch +Patch308: 0008-tpm2_encode-Fix-setting-emptyAuth-in-generated-pem-f.patch BuildRequires: git BuildRequires: make @@ -89,6 +105,23 @@ autoreconf -i %{_mandir}/man1/tss2_*.1.gz %changelog +* Wed Apr 24 2025 Štěpán Horáček - 5.2-6 +- Backport upstream fixes. + Resolves: RHEL-72772 + +* Fri Mar 21 2025 Davide Cavalca - 5.2-5 +- Backport upstream bugfix for tpm2_eventlog + Resolves: RHEL-83453 + +* Wed Jun 19 2024 Štěpán Horáček - 5.2-4 +- Backport upstream fixes. +- tpm2_checkquote: Fix check of magic number. (CVE-2024-29038) +- tpm2_checkquote: Add comparison of pcr selection. (CVE-2024-29039) +- Fix check of magic number. + Resolves: RHEL-23198 + Resolves: RHEL-41031 + Resolves: RHEL-41035 + * Wed May 24 2023 Štěpán Horáček - 5.2-3 - Backport fixes. - Add tpm2_encodeobject tool.