Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package pcr-oracle for openSUSE:Factory checked in at 2025-10-08 18:12:33 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/pcr-oracle (Old) and /work/SRC/openSUSE:Factory/.pcr-oracle.new.11973 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "pcr-oracle" Wed Oct 8 18:12:33 2025 rev:22 rq:1309446 version:0.5.8 Changes: -------- --- /work/SRC/openSUSE:Factory/pcr-oracle/pcr-oracle.changes 2025-06-01 21:36:21.620808105 +0200 +++ /work/SRC/openSUSE:Factory/.pcr-oracle.new.11973/pcr-oracle.changes 2025-10-08 18:12:59.486553828 +0200 @@ -1,0 +2,7 @@ +Tue Oct 7 02:45:01 UTC 2025 - Gary Ching-Pang Lin <[email protected]> + +- Update to 0.5.8 + + Fix unsealing failure when using non default PCR bank + + Extra checks for TPM self-test (bsc#1249079) + +------------------------------------------------------------------- Old: ---- pcr-oracle-0.5.7.tar.xz New: ---- pcr-oracle-0.5.8.tar.xz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ pcr-oracle.spec ++++++ --- /var/tmp/diff_new_pack.NfyINB/_old 2025-10-08 18:13:00.394591727 +0200 +++ /var/tmp/diff_new_pack.NfyINB/_new 2025-10-08 18:13:00.394591727 +0200 @@ -18,7 +18,7 @@ Name: pcr-oracle -Version: 0.5.7 +Version: 0.5.8 Release: 0 Summary: Predict TPM PCR values License: GPL-2.0-or-later ++++++ _service ++++++ --- /var/tmp/diff_new_pack.NfyINB/_old 2025-10-08 18:13:00.434593397 +0200 +++ /var/tmp/diff_new_pack.NfyINB/_new 2025-10-08 18:13:00.438593564 +0200 @@ -7,7 +7,7 @@ <param name="url">https://github.com/openSUSE/pcr-oracle.git</param> <param name="filename">pcr-oracle</param> <param name="versionformat">@PARENT_TAG@</param> - <param name="revision">refs/tags/0.5.7</param> + <param name="revision">refs/tags/0.5.8</param> </service> <service name="recompress" mode="disabled"> <param name="file">pcr-oracle*.tar</param> ++++++ pcr-oracle-0.5.7.tar.xz -> pcr-oracle-0.5.8.tar.xz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pcr-oracle-0.5.7/configure new/pcr-oracle-0.5.8/configure --- old/pcr-oracle-0.5.7/configure 2025-05-29 09:26:41.000000000 +0200 +++ new/pcr-oracle-0.5.8/configure 2025-10-07 04:39:23.000000000 +0200 @@ -12,7 +12,7 @@ # Invoke with --help for a description of options # # microconf:begin -# version 0.5.7 +# version 0.5.8 # require libtss2 # require json # require libfdisk diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pcr-oracle-0.5.7/microconf/version new/pcr-oracle-0.5.8/microconf/version --- old/pcr-oracle-0.5.7/microconf/version 2025-05-29 09:26:41.000000000 +0200 +++ new/pcr-oracle-0.5.8/microconf/version 2025-10-07 04:39:23.000000000 +0200 @@ -1 +1 @@ -uc_version=0.5.7 +uc_version=0.5.8 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pcr-oracle-0.5.7/src/pcr-policy.c new/pcr-oracle-0.5.8/src/pcr-policy.c --- old/pcr-oracle-0.5.7/src/pcr-policy.c 2025-05-29 09:26:41.000000000 +0200 +++ new/pcr-oracle-0.5.8/src/pcr-policy.c 2025-10-07 04:39:23.000000000 +0200 @@ -62,7 +62,7 @@ const stored_key_t *public_key_file); }; -static TPM2B_PUBLIC RSA_SRK_template = { +TPM2B_PUBLIC RSA_SRK_template = { .size = sizeof(TPMT_PUBLIC), .publicArea = { .type = TPM2_ALG_RSA, @@ -88,7 +88,7 @@ } }; -static TPM2B_PUBLIC ECC_SRK_template = { +TPM2B_PUBLIC ECC_SRK_template = { .size = sizeof(TPMT_PUBLIC), .publicArea = { .type = TPM2_ALG_ECC, @@ -477,7 +477,7 @@ rc = Esys_HashSequenceStart(esys_context, ESYS_TR_NONE, ESYS_TR_NONE, ESYS_TR_NONE, &null_auth, - bank->algo_info->tcg_id, + TPM2_ALG_SHA256, &sequence_handle); if (!tss_check_error(rc, "Esys_HashSequenceStart failed")) @@ -1142,52 +1142,6 @@ return ok; } -bool -old_pcr_authorized_policy_seal_secret(const char *authpolicy_path, const char *input_path, const char *output_path) -{ - ESYS_CONTEXT *esys_context = tss_esys_context(); - TPM2B_DIGEST *authorized_policy = NULL; - TPM2B_SENSITIVE_DATA *secret = NULL; - TPM2B_PRIVATE *sealed_private = NULL; - TPM2B_PUBLIC *sealed_public = NULL; - ESYS_TR srk_handle = ESYS_TR_NONE; - bool ok = false; - - if (!(secret = read_secret(input_path))) - goto cleanup; - - if (!(authorized_policy = read_digest(authpolicy_path))) - goto cleanup; - - /* On my machine, the TPM needs 20 seconds to derive the SRK in CreatePrimary */ - infomsg("Sealing secret - this may take a moment\n"); - - if (!esys_create_primary(esys_context, &srk_handle)) - goto cleanup; - - if (!esys_create(esys_context, srk_handle, authorized_policy, secret, &sealed_private, &sealed_public)) - goto cleanup; - - ok = write_sealed_secret(output_path, sealed_public, sealed_private); - - if (ok) - infomsg("Sealed secret written to %s\n", output_path?: "(standard output)"); - -cleanup: - if (sealed_private) - free(sealed_private); - if (sealed_public) - free(sealed_public); - if (authorized_policy) - free(authorized_policy); - if (secret) - free_secret(secret); - - esys_flush_context(esys_context, &srk_handle); - return ok; -} - - /* * The "signing" part of using authorized policies consists of hashing together the set of * expected PCR values, and signing the resulting digest. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pcr-oracle-0.5.7/src/tpm.c new/pcr-oracle-0.5.8/src/tpm.c --- old/pcr-oracle-0.5.7/src/tpm.c 2025-05-29 09:26:41.000000000 +0200 +++ new/pcr-oracle-0.5.8/src/tpm.c 2025-10-07 04:39:23.000000000 +0200 @@ -85,14 +85,233 @@ return esys_ctx; } +static bool +tpm_get_tpm_property(TPM2_PT property, uint32_t *value) +{ + ESYS_CONTEXT *esys_ctx = tss_esys_context(); + TPMS_CAPABILITY_DATA *cap_data = NULL; + TPMI_YES_NO more_data; + TPML_TAGGED_TPM_PROPERTY *props = NULL; + TSS2_RC rc; + bool okay = false; + + if (value == NULL) + return false; + + rc = Esys_GetCapability(esys_ctx, ESYS_TR_NONE, ESYS_TR_NONE, + ESYS_TR_NONE, TPM2_CAP_TPM_PROPERTIES, property, + 1, &more_data, &cap_data); + if (rc != TSS2_RC_SUCCESS) + return tss_check_error(rc, "Esys_GetCapability (TPM_PROPERTIES) failed"); + + if (cap_data == NULL) { + error("Empty CAP data (TPM_PROPERTIES)\n"); + return false; + } + + if (cap_data->capability != TPM2_CAP_TPM_PROPERTIES) { + error("Wrong CAP data (TPM_PROPERTIES)\n"); + goto out; + } + + props = &cap_data->data.tpmProperties; + if (props->count != 1) { + error("Got more than 1 property\n"); + goto out; + } + + if (props->tpmProperty[0].property != property) { + error("Property not match\n"); + goto out; + } + + *value = props->tpmProperty[0].value; + + okay = true; +out: + if (cap_data) + free(cap_data); + + return okay; +} + +#ifdef TPM2_CAP_AUTH_POLICIES +static bool +tpm_get_auth_policies(TPM2_HANDLE hierarchy, TPMS_CAPABILITY_DATA **cap_data) +{ + ESYS_CONTEXT *esys_ctx = tss_esys_context(); + TPMI_YES_NO more_data; + TSS2_RC rc; + + rc = Esys_GetCapability(esys_ctx, ESYS_TR_NONE, ESYS_TR_NONE, + ESYS_TR_NONE, TPM2_CAP_AUTH_POLICIES, hierarchy, + TPM2_MAX_TAGGED_POLICIES, &more_data, cap_data); + if (rc != TSS2_RC_SUCCESS) + return tss_check_error(rc, "Esys_GetCapability (AUTH_POLICIES) failed"); + + if (*cap_data == NULL) { + error("Empty CAP data (AUTH_POLICIES)\n"); + return false; + } + + if ((*cap_data)->capability != TPM2_CAP_AUTH_POLICIES) { + error("Wrong CAP data (AUTH_POLICIES)\n"); + return false; + } + + return true; +} + +static bool +tpm_check_auth_policies(TPM2_HANDLE hierarchy) +{ + TPMS_CAPABILITY_DATA *cap_data = NULL; + TPML_TAGGED_POLICY *policies = NULL; + uint32_t i; + bool okay = false; + + if (!tpm_get_auth_policies(hierarchy, &cap_data)) + goto out; + + policies = &cap_data->data.authPolicies; + for (i = 0; i < policies->count; i++) { + if (policies->policies[i].policyHash.hashAlg != TPM2_ALG_NULL) { + error("Tagged policy NON-NULL Hash Algorithm\n"); + goto out; + } + } + + okay = true; +out: + if (cap_data) + free(cap_data); + + return okay; +} +#endif + +static bool +tpm_check_capabilities(void) +{ + uint32_t prop_startup, prop_permanent; + + /* Check PropertyStartupClear (TPM2_PT_STARTUP_CLEAR) */ + if (!tpm_get_tpm_property(TPM2_PT_STARTUP_CLEAR, &prop_startup)) { + error("Failed to get PropertyStartupClear\n"); + return false; + } + + if ((prop_startup & TPMA_STARTUP_CLEAR_SHENABLE) == 0) { + error("Storage hierarchy not enabled\n"); + return false; + } + + if ((prop_startup & TPMA_STARTUP_CLEAR_EHENABLE) == 0) { + error("Endorsement hierarchy not enabled\n"); + return false; + } + + /* Check PropertyPermanent (TPM2_PT_PERMANENT) */ + if (!tpm_get_tpm_property(TPM2_PT_PERMANENT, &prop_permanent)) { + error("Failed to get PropertyPermanent\n"); + return false; + } + + if ((prop_permanent & TPMA_PERMANENT_OWNERAUTHSET) != 0) { + error("TPM2 Owner Authorization set\n"); + return false; + } + + if ((prop_permanent & TPMA_PERMANENT_ENDORSEMENTAUTHSET) != 0) { + error("TPM2 Endorsement Authorization set\n"); + return false; + } + + if ((prop_permanent & TPMA_PERMANENT_LOCKOUTAUTHSET) != 0) { + error("TPM2 Lockout Authorization set\n"); + return false; + } + + if ((prop_permanent & TPMA_PERMANENT_INLOCKOUT) != 0) { + error("TPM2 in lockout\n"); + return false; + } + +#ifdef TPM2_CAP_AUTH_POLICIES + /* + * Ensure that there is no authorization policy associated with the + * following hierarchies: TPM2_RH_LOCKOUT, TPM2_RH_OWNER, and + * TPM2_RH_ENDORSEMENT + */ + if (!tpm_check_auth_policies(TPM2_RH_LOCKOUT)) { + error("Error from LockOut handle\n"); + return false; + } + + if (!tpm_check_auth_policies(TPM2_RH_OWNER)) { + error("Error from Owner handle\n"); + return false; + } + + if (!tpm_check_auth_policies(TPM2_RH_ENDORSEMENT)) { + error("Error from Endorsement handle\n"); + return false; + } +#endif + + return true; +} + +static bool +tpm_check_srk(void) +{ + ESYS_CONTEXT *esys_ctx = tss_esys_context(); + TPMT_PUBLIC_PARMS parms = {0}; + TSS2_RC rc; + + /* Test RSA SRK */ + parms.type = TPM2_ALG_RSA; + memcpy(&parms.parameters, &RSA_SRK_template.publicArea.parameters, + sizeof(TPMU_PUBLIC_PARMS)); + + rc = Esys_TestParms(esys_ctx, ESYS_TR_NONE, ESYS_TR_NONE, ESYS_TR_NONE, &parms); + if (rc != TSS2_RC_SUCCESS) + return tss_check_error(rc, "RSA SRK test failed"); + + memset(&parms, 0, sizeof(TPMT_PUBLIC_PARMS)); + + /* Test ECC SRK */ + parms.type = TPM2_ALG_ECC; + memcpy(&parms.parameters, &ECC_SRK_template.publicArea.parameters, + sizeof(TPMU_PUBLIC_PARMS)); + + rc = Esys_TestParms(esys_ctx, ESYS_TR_NONE, ESYS_TR_NONE, ESYS_TR_NONE, &parms); + if (rc != TSS2_RC_SUCCESS) + return tss_check_error(rc, "ECC SRK test failed"); + + return true; +} + bool tpm_selftest(bool fulltest) { ESYS_CONTEXT *esys_ctx = tss_esys_context(); TSS2_RC rc; + /* TPM self test */ rc = Esys_SelfTest(esys_ctx, ESYS_TR_NONE, ESYS_TR_NONE, ESYS_TR_NONE, fulltest); - return tss_check_error(rc, "TPM self test failed"); + if (rc != TSS2_RC_SUCCESS) + return tss_check_error(rc, "TPM self test failed"); + + /* Capability check */ + if(!tpm_check_capabilities()) + return false; + + /* SRK template test */ + if (!tpm_check_srk()) + return false; + + return true; } bool @@ -119,9 +338,8 @@ ESYS_TR_NONE, &rsa_parms); if (rc == TSS2_RC_SUCCESS) okay = true; - else if (rc != (TPM2_RC_VALUE | TPM2_RC_P | TPM2_RC_1)) { - tss_check_error(rc, "Esys_CreatePrimary failed"); - } + else if (rc != (TPM2_RC_VALUE | TPM2_RC_P | TPM2_RC_1)) + tss_check_error(rc, "Esys_TestParms failed"); return okay; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pcr-oracle-0.5.7/src/tpm.h new/pcr-oracle-0.5.8/src/tpm.h --- old/pcr-oracle-0.5.7/src/tpm.h 2025-05-29 09:26:41.000000000 +0200 +++ new/pcr-oracle-0.5.8/src/tpm.h 2025-10-07 04:39:23.000000000 +0200 @@ -28,6 +28,9 @@ extern uint32_t esys_tr_rh_null; extern uint32_t esys_tr_rh_owner; +extern TPM2B_PUBLIC RSA_SRK_template; +extern TPM2B_PUBLIC ECC_SRK_template; + extern ESYS_CONTEXT * tss_esys_context(void); extern void tss_print_error(int rc, const char *msg);
