Skip to content

Commit

Permalink
FAPI: Add Policy Template.
Browse files Browse the repository at this point in the history
The instantiation and execution of policy template is added.
Fixes: #2509

Signed-off-by: Juergen Repp <juergen_repp@web.de>
  • Loading branch information
JuergenReppSIT authored and cplappert committed Dec 15, 2022
1 parent 63fc2ab commit 2642b76
Show file tree
Hide file tree
Showing 3 changed files with 190 additions and 2 deletions.
98 changes: 98 additions & 0 deletions src/tss2-fapi/ifapi_policy_calculate.c
Original file line number Diff line number Diff line change
Expand Up @@ -1198,6 +1198,95 @@ ifapi_calculate_policy_or(
return r;
}

/** Calculate a policy digest for policy template.
*
* The template hash will be derived from template_public if no template hash
* is provided.
*
* @param[in] policy The policy with the template hash or the public data used to
* compute the template hash.
* @param[in,out] current_digest The digest list which has to be updated.
* @param[in] current_hash_alg The hash algorithm used for the policy computation.
*
* @retval TSS2_RC_SUCCESS on success.
* @retval TSS2_FAPI_RC_BAD_VALUE if an invalid value was passed into
* the function.
* @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
* @retval TSS2_FAPI_RC_MEMORY if not enough memory can be allocated.
* @retval TSS2_FAPI_RC_GENERAL_FAILURE if an internal error occurred.
*/
TSS2_RC
ifapi_calculate_policy_template(
TPMS_POLICYTEMPLATE *policy,
TPML_DIGEST_VALUES *current_digest,
TPMI_ALG_HASH current_hash_alg)

{
TSS2_RC r = TSS2_RC_SUCCESS;
size_t digest_idx;
size_t hash_size;
TPM2B_DIGEST computed_template_hash;
TPM2B_DIGEST *used_template_hash;
IFAPI_CRYPTO_CONTEXT_BLOB *cryptoContext = NULL;
uint8_t buffer[sizeof(TPM2B_PUBLIC)];
size_t offset = 0;
size_t digest_size;

LOG_DEBUG("call");

if (!(hash_size = ifapi_hash_get_digest_size(current_hash_alg))) {
goto_error(r, TSS2_FAPI_RC_BAD_VALUE,
"Unsupported hash algorithm (%" PRIu16 ")", cleanup,
current_hash_alg);
}

/* Compute of the index of the current policy in the passed digest list */
r = get_policy_digest_idx(current_digest, current_hash_alg, &digest_idx);
return_if_error(r, "Get hash alg for digest.");

if (policy->templateHash.size == 0) {
used_template_hash = &computed_template_hash;
r = Tss2_MU_TPMT_PUBLIC_Marshal(&policy->templatePublic.publicArea,
&buffer[0], sizeof(TPMT_PUBLIC), &offset);
return_if_error(r, "Marshaling TPMT_PUBLIC");

r = ifapi_crypto_hash_start(&cryptoContext, current_hash_alg);
return_if_error(r, "crypto hash start");

HASH_UPDATE_BUFFER(cryptoContext,
&buffer[0], offset,
r, cleanup);
r = ifapi_crypto_hash_finish(&cryptoContext,
&used_template_hash->buffer[0],
&digest_size);
goto_if_error(r, "crypto hash finish", cleanup);
used_template_hash->size = digest_size;
} else {
used_template_hash = &policy->templateHash;
}

LOG_TRACE("Compute policy template");
r = ifapi_crypto_hash_start(&cryptoContext, current_hash_alg);
return_if_error(r, "crypto hash start");

HASH_UPDATE(cryptoContext, TPM2_CC, TPM2_CC_PolicyTemplate, r,
cleanup);
HASH_UPDATE_BUFFER(cryptoContext, &used_template_hash->buffer[0],
used_template_hash->size, r, cleanup);
r = ifapi_crypto_hash_finish(&cryptoContext,
(uint8_t *) & current_digest->
digests[digest_idx].digest, &hash_size);
return_if_error(r, "crypto hash finish");

LOGBLOB_DEBUG((uint8_t *) & current_digest->digests[digest_idx].digest,
hash_size, "Policy Duplicate digest");

cleanup:
if (cryptoContext)
ifapi_crypto_hash_abort(&cryptoContext);
return r;
}

/** Compute policy digest for a list of policies.
*
* Every policy in the list will update the previous policy. Thus the final
Expand Down Expand Up @@ -1362,6 +1451,15 @@ ifapi_calculate_policy(
/* This does not alter the policyDigest */
break;

case POLICYTEMPLATE:
r = ifapi_calculate_policy_template(&policy->elements[i].element.
PolicyTemplate,
&policy->elements[i].
policyDigests, hash_alg);
return_if_error(r, "Compute policy template");

break;

default:
return_error(TSS2_FAPI_RC_BAD_VALUE,
"Policy not implemented");
Expand Down
90 changes: 90 additions & 0 deletions src/tss2-fapi/ifapi_policy_execute.c
Original file line number Diff line number Diff line change
Expand Up @@ -1505,6 +1505,89 @@ execute_policy_action(
}
}

/** Execute policy template.
*
* @param[in,out] *esys_ctx The ESAPI context which is needed to execute the
* policy command.
* @param[in,out] policy The policy with the template digest or the public data
* used to compute the template digest.
* @param[in,out] current_policy The policy context which stores the state
* of the policy execution.
* @retval TSS2_RC_SUCCESS on success.
* @retval TSS2_FAPI_RC_TRY_AGAIN if an I/O operation is not finished yet and
* this function needs to be called again.
* @retval TSS2_FAPI_RC_BAD_SEQUENCE if the context has an asynchronous
* operation already pending.
* @retval TSS2_ESYS_RC_* possible error codes of ESAPI.
*/
static TSS2_RC
execute_policy_template(
ESYS_CONTEXT *esys_ctx,
TPMS_POLICYTEMPLATE *policy,
IFAPI_POLICY_EXEC_CTX *current_policy)
{
TSS2_RC r = TSS2_RC_SUCCESS;

LOG_TRACE("call");

TPM2B_DIGEST computed_template_hash;
TPM2B_DIGEST *used_template_hash;
IFAPI_CRYPTO_CONTEXT_BLOB *cryptoContext = NULL;
uint8_t buffer[sizeof(TPM2B_PUBLIC)];
size_t offset = 0;
size_t digest_size;


switch (current_policy->state) {
statecase(current_policy->state, POLICY_EXECUTE_INIT)
if (policy->templateHash.size == 0) {
used_template_hash = &computed_template_hash;
r = Tss2_MU_TPMT_PUBLIC_Marshal(&policy->templatePublic.publicArea,
&buffer[0], sizeof(TPMT_PUBLIC), &offset);
return_if_error(r, "Marshaling TPMT_PUBLIC");

r = ifapi_crypto_hash_start(&cryptoContext, current_policy->hash_alg);
return_if_error(r, "crypto hash start");

HASH_UPDATE_BUFFER(cryptoContext,
&buffer[0], offset,
r, cleanup);
r = ifapi_crypto_hash_finish(&cryptoContext,
&used_template_hash->buffer[0],
&digest_size);
goto_if_error(r, "crypto hash finish", cleanup);
used_template_hash->size = digest_size;

} else {
used_template_hash = &policy->templateHash;
}

/* Prepare the policy execution. */
r = Esys_PolicyTemplate_Async(esys_ctx,
current_policy->session,
ESYS_TR_NONE, ESYS_TR_NONE, ESYS_TR_NONE,
used_template_hash);
return_if_error(r, "Execute PolicyTemplate.");
fallthrough;

statecase(current_policy->state, POLICY_EXECUTE_FINISH)
/* Finalize the policy execution if possible. */
r = Esys_PolicyTemplate_Finish(esys_ctx);
try_again_or_error(r, "Execute PolicyTemplate_Finish.");

current_policy->state = POLICY_EXECUTE_INIT;
return r;

statecasedefault(current_policy->state)
}
return r;

cleanup:
if (cryptoContext)
ifapi_crypto_hash_abort(&cryptoContext);
return r;
}

/** Execute a policy element depending on the type.
*
* @param[in,out] *esys_ctx The ESAPI context which is needed to execute the
Expand Down Expand Up @@ -1657,6 +1740,13 @@ execute_policy_element(
try_again_or_error_goto(r, "Execute policy action", error);
break;

case POLICYTEMPLATE:
r = execute_policy_template(esys_ctx,
&policy->element.PolicyTemplate,
current_policy);
try_again_or_error_goto(r, "Execute policy template", error);
break;

default:
return_error(TSS2_FAPI_RC_GENERAL_FAILURE,
"Policy not implemented");
Expand Down
4 changes: 2 additions & 2 deletions src/tss2-fapi/ifapi_policy_json_serialize.c
Original file line number Diff line number Diff line change
Expand Up @@ -803,10 +803,10 @@ ifapi_json_TPMS_POLICYTEMPLATE_serialize(const TPMS_POLICYTEMPLATE *in,

json_object_object_add(*jso, "templateHash", jso2);
}
if (in->templatePublic.size != 0) {
if (in->templatePublic.publicArea.type) {
jso2 = NULL;
cond_cnt++;
r = ifapi_json_TPM2B_PUBLIC_serialize(&in->templatePublic, &jso2);
r = ifapi_json_TPMT_PUBLIC_serialize(&in->templatePublic.publicArea, &jso2);
return_if_error(r, "Serialize TPM2B_PUBLIC");

json_object_object_add(*jso, "templatePublic", jso2);
Expand Down

0 comments on commit 2642b76

Please sign in to comment.