diff --git a/src/lib/tpm.c b/src/lib/tpm.c index d093b653..e8900ea9 100644 --- a/src/lib/tpm.c +++ b/src/lib/tpm.c @@ -4012,6 +4012,55 @@ CK_RV tpm2_getmechanisms(tpm_ctx *ctx, CK_MECHANISM_TYPE *mechanism_list, CK_ULO } #ifdef HAVE_POLICY +static TSS2_RC tpm2_policy_get_pcr(TSS2_POLICY_PCR_SELECTION *selection, + TPML_PCR_SELECTION *out_selection, + TPML_DIGEST *out_digest, + void *userdata) +{ + + TPML_PCR_SELECTION in_pcr_selection = {0}; + if (selection->type == TSS2_POLICY_PCR_SELECTOR_PCR_SELECTION) { + in_pcr_selection = selection->selections.pcr_selection; + } else { + in_pcr_selection.count = 1; + + TPMS_PCR_SELECTION *pcr_bank = &in_pcr_selection.pcrSelections[0]; + TPMS_PCR_SELECT *pcr_select = &selection->selections.pcr_select; + + pcr_bank->hash = TPM2_ALG_SHA256; + pcr_bank->sizeofSelect = pcr_select->sizeofSelect; + memcpy(pcr_bank->pcrSelect, pcr_select->pcrSelect, pcr_bank->sizeofSelect); + } + + ESYS_CONTEXT *esys_ctx = userdata; + + UINT32 pcr_update_counter; + TPML_PCR_SELECTION *pcr_selection = NULL; + TPML_DIGEST *pcr_values = NULL; + + TSS2_RC rc = Esys_PCR_Read(esys_ctx, + ESYS_TR_NONE, + ESYS_TR_NONE, + ESYS_TR_NONE, + &in_pcr_selection, + &pcr_update_counter, + &pcr_selection, + &pcr_values); + if (rc != TSS2_RC_SUCCESS) { + LOGE("Esys_PCR_Read: %s:", Tss2_RC_Decode(rc)); + free(pcr_selection); + free(pcr_values); + return rc; + } + + *out_selection = *pcr_selection; + *out_digest = *pcr_values; + + free(pcr_selection); + free(pcr_values); + return TSS2_RC_SUCCESS; +} + CK_RV tpm2_execute_policy(tpm_ctx *ctx, TSS2_POLICY_CTX *policy_ctx, uint32_t handle) { @@ -4025,8 +4074,18 @@ CK_RV tpm2_execute_policy(tpm_ctx *ctx, TSS2_POLICY_CTX *policy_ctx, uint32_t ha .mode = { .aes = TPM2_ALG_CFB } }; + TSS2_POLICY_CALC_CALLBACKS calc_callbacks = {0}; + calc_callbacks.cbpcr = &tpm2_policy_get_pcr; + calc_callbacks.cbpcr_userdata = ctx->esys_ctx; + TSS2_RC rc; + rc = Tss2_PolicySetCalcCallbacks(policy_ctx, &calc_callbacks); + if (rc != TSS2_RC_SUCCESS) { + LOGE("Tss2_PolicySetCalcCallbacks: %s:", Tss2_RC_Decode(rc)); + return CKR_GENERAL_ERROR; + } + /* XXX should we cache the session or running multiple policies is unlikely? */ ESYS_TR policy_session = ESYS_TR_NONE; rc = Esys_StartAuthSession(ctx->esys_ctx,