/* SPDX-License-Identifier: BSD-2-Clause */
/*******************************************************************************
 * Copyright 2018-2019, Fraunhofer SIT sponsored by Infineon Technologies AG
 * All rights reserved.
 *******************************************************************************/

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#include <string.h>
#include <stdlib.h>

#include "tss2_mu.h"
#include "fapi_util.h"
#include "fapi_crypto.h"
#include "fapi_policy.h"
#include "ifapi_helpers.h"
#include "ifapi_json_deserialize.h"
#include "tpm_json_deserialize.h"
#define LOGMODULE fapi
#include "util/log.h"
#include "util/aux_util.h"

/** Copy policy digest.
 *
 * One digest is copied from certain position in a policy list to the
 * same position in a second list.
 *
 * @param[out] dest The digest list to which the new value is added.
 * @param[in]  src The digest list with the value to be copied.
 * @param[in]  digest_idx The index of the digest to be copied.
 * @param[in]  hash_size The number of bytes to be copied.
 * @param[in]  txt Text which will be used for additional logging information..
 * @retval TSS2_RC_SUCCESS on success.
 */
static void
copy_policy_digest(TPML_DIGEST_VALUES *dest, TPML_DIGEST_VALUES *src,
                   size_t digest_idx, size_t hash_size, char *txt)
{
    (void)(txt); /* If max log-leve < debug, this param is unused */
    memcpy(&dest->digests[digest_idx].digest, &src->digests[digest_idx].digest,
           hash_size);
    dest->digests[digest_idx].hashAlg = src->digests[digest_idx].hashAlg;
    LOGBLOB_DEBUG((uint8_t *)&dest->digests[digest_idx].digest, hash_size,
                  "%s : Copy digest size: %zu", txt, hash_size);
    dest->count = src->count;
}

/** Logdefault policy digest.
 *
 * @param[in] dest The digest to be logged.
 * @param[in] digest_idx The index of the digest to be logged
 * @param[in] hash_size The number of bytes to be logged
 * @param[in] txt Text which will be used for additional logging information.
 */
static void
log_policy_digest(TPML_DIGEST_VALUES *dest, size_t digest_idx, size_t hash_size,
                  char *txt)
{
    (void)(dest);(void)(digest_idx);(void)(hash_size);(void)(txt);
    /* If max log-leve < debug, this param is unused */
    LOGBLOB_DEBUG((uint8_t *)&dest->digests[digest_idx].digest, hash_size,
                  "Digest %s", txt);
}

/** Calculate a policy digest for a certain PCR selection.
 *
 * From a PCR list the list of PCR values and the corresponding PCR digest
 * is computed. The passed policy digest will be extended with this data
 * and also with the policy command code.
 *
 * @param[in] policy The policy with the list of selected PCRs.
 * @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_GENERAL_FAILURE if an internal error occurred.
 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
 * @retval TSS2_FAPI_RC_MEMORY if not enough memory can be allocated.
 */
TSS2_RC
ifapi_compute_policy_pcr(
    TPMS_POLICYPCR *policy,
    TPML_DIGEST_VALUES *current_digest,
    TPMI_ALG_HASH current_hash_alg)
{
    TSS2_RC r = TSS2_RC_SUCCESS;
    IFAPI_CRYPTO_CONTEXT_BLOB *cryptoContext = NULL;
    TPML_PCR_SELECTION pcr_selection;
    size_t digest_idx;
    TPM2B_DIGEST pcr_digest;
    size_t hash_size;

    LOG_TRACE("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.");

    /* Compute PCR selection and pcr digest */
    r = ifapi_compute_policy_digest(policy->pcrs, &pcr_selection,
                                    current_hash_alg, &pcr_digest);
    return_if_error(r, "Compute policy digest and selection.");

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

    /* Update the passed policy. */
    HASH_UPDATE_BUFFER(cryptoContext,
                       &current_digest->digests[digest_idx].digest, hash_size,
                       r, cleanup);
    HASH_UPDATE(cryptoContext, TPM2_CC, TPM2_CC_PolicyPCR, r, cleanup);
    /* The marshaled version of the digest list will be added. */
    HASH_UPDATE(cryptoContext, TPML_PCR_SELECTION, &pcr_selection, r, cleanup);
    HASH_UPDATE_BUFFER(cryptoContext, &pcr_digest.buffer[0], 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");

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

/** Calculate a policy digest for a TPM2B object name, and a policy reference.
 *
 * A policy hash based on a passed policy digest, the policy command code,
 * optionally the name, and the policy reference will be computed.
 * The calculation is carried out in two steps. First a hash with the
 * command code and the passed digest, and optionaly the name is computed.
 * This digest, together with the other parameters is used to compute
 * the final policy digest.
 *
 * @param[in] command_code The TPM command code of the policy command.
 * @param[in] name The name of a key or a NV object.
 * @param[in] policyRef The policy reference value.
 * @param[in] hash_size The digest size of the used hash algorithm.
 * @param[in] current_hash_alg The used has algorithm.
 * @param[in,out] digest The policy digest which will be extended.
 *
 * @retval TSS2_RC_SUCCESS on success.
 * @retval TSS2_FAPI_RC_GENERAL_FAILURE if an internal error occurred.
 * @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_BAD_VALUE if an invalid value was passed into
 *         the function.
 */
static TSS2_RC
calculate_policy_key_param(
    TPM2_CC command_code,
    TPM2B_NAME *name,
    TPM2B_NONCE *policyRef,
    size_t hash_size,
    TPMI_ALG_HASH current_hash_alg,
    TPMU_HA *digest)
{
    TSS2_RC r = TSS2_RC_SUCCESS;
    IFAPI_CRYPTO_CONTEXT_BLOB *cryptoContext = NULL;

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

    LOGBLOB_DEBUG((uint8_t *) digest, hash_size, "Digest Start");

    /* First compute hash from passed policy digest and command code
       and optionally the object name */
    HASH_UPDATE_BUFFER(cryptoContext, digest, hash_size, r, cleanup);
    HASH_UPDATE(cryptoContext, TPM2_CC, command_code, r, cleanup);
    if (name && name->size > 0) {
        LOGBLOB_DEBUG(&name->name[0], name->size, "Key name");
        HASH_UPDATE_BUFFER(cryptoContext, &name->name[0],
                           name->size, r, cleanup);
    }
    r = ifapi_crypto_hash_finish(&cryptoContext,
                                 (uint8_t *) digest, &hash_size);
    LOGBLOB_DEBUG((uint8_t *) digest, hash_size, "Digest Finish");
    return_if_error(r, "crypto hash finish");

    /* Use policyRef for second hash computation */
    if (policyRef) {
        r = ifapi_crypto_hash_start(&cryptoContext, current_hash_alg);
        return_if_error(r, "crypto hash start");

        HASH_UPDATE_BUFFER(cryptoContext, digest, hash_size, r, cleanup);
        HASH_UPDATE_BUFFER(cryptoContext, &policyRef->buffer[0],
                           policyRef->size, r, cleanup);
        r = ifapi_crypto_hash_finish(&cryptoContext,
                                     (uint8_t *) digest, &hash_size);
        return_if_error(r, "crypto hash finish");
    }

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

/** Calculate a policy digest for a signed policy.
 *
 * Based on the command code, the public key, and the policy reference
 * stored in the policy the new policy digest is computed by the function
 * calculate_policy_key_param().
 *
 * @param[in] policy The policy with the public key and the policy reference.
 * @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_GENERAL_FAILURE if an internal error occurred.
 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
 * @retval TSS2_FAPI_RC_MEMORY if not enough memory can be allocated.
 */
TSS2_RC
ifapi_calculate_policy_signed(
    TPMS_POLICYSIGNED *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;

    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.");

    r = calculate_policy_key_param(TPM2_CC_PolicySigned,
                                   &policy->publicKey,
                                   &policy->policyRef, hash_size,
                                   current_hash_alg,
                                   &current_digest->digests[digest_idx].digest);
    goto_if_error(r, "crypto hash start", cleanup);

cleanup:
    return r;
}

/** Calculate a policy digest for a policy stored in an approved NV index.
 *
 * Based on the command code, and the computed NV name the new policy digest
 * is computed by the function calculate_policy_key_param().
 *
 * @param[in] policy The policy with the public information of the NV index.
 * @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_authorize_nv(
    TPMS_POLICYAUTHORIZENV *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_NAME nv_name;

    LOG_DEBUG("call");

    /* Written flag has to be set for policy calculation, because during
       policy execution it will be set. */
    policy->nvPublic.nvPublic.attributes |= TPMA_NV_WRITTEN;

    r = ifapi_nv_get_name(&policy->nvPublic, &nv_name);
    return_if_error(r, "Compute NV name");

    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.");

    r = calculate_policy_key_param(TPM2_CC_PolicyAuthorizeNV,
                                   &nv_name,
                                   NULL, hash_size, current_hash_alg,
                                   &current_digest->digests[digest_idx].digest);
    goto_if_error(r, "crypto hash start", cleanup);

cleanup:
    return r;
}

/** Calculate a policy digest to allow duplication force a selected new parent.
 *
 * Based on the command code, the name of the new parent, and the include object
 * switch the new policy digest is computed.
 *
 * @param[in] policy The policy with the new parent information.
 * @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_GENERAL_FAILURE if an internal error occurred.
 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
 * @retval TSS2_FAPI_RC_MEMORY if not enough memory can be allocated.
 */
TSS2_RC
ifapi_calculate_policy_duplicate(
    TPMS_POLICYDUPLICATIONSELECT *policy,
    TPML_DIGEST_VALUES *current_digest,
    TPMI_ALG_HASH current_hash_alg)
{
    TSS2_RC r = TSS2_RC_SUCCESS;
    IFAPI_CRYPTO_CONTEXT_BLOB *cryptoContext = NULL;
    size_t digest_idx;
    size_t hash_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.");

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

    /* Update the policy digest */
    HASH_UPDATE_BUFFER(cryptoContext,
                       &current_digest->digests[digest_idx].digest, hash_size,
                       r, cleanup);
    HASH_UPDATE(cryptoContext, TPM2_CC, TPM2_CC_PolicyDuplicationSelect, r,
                cleanup);
    LOGBLOB_DEBUG(&policy->newParentName.name[0], policy->newParentName.size,
                  "Policy Duplicate Parent Name");
    HASH_UPDATE_BUFFER(cryptoContext, &policy->newParentName.name[0],
                       policy->newParentName.size, r, cleanup);
    HASH_UPDATE(cryptoContext, BYTE, policy->includeObject, 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;
}

/** Calculate a policy digest for a placeholder policy.
 *
 * The placeholder policy can be extended during execution by a
 * signed policy, which can be verified by using the parameters of
 * this placeholder policy.
 * Based on the command code, the key name of the signing key and
 * a policy reference the new policy digest is computed by the
 * function calculate_policy_key_param().
 *
 * @param[in] policy The policy with the name of the public key and the
 *                   policy reference.
 * @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_GENERAL_FAILURE if an internal error occurred.
 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
 * @retval TSS2_FAPI_RC_MEMORY if not enough memory can be allocated.
 */
TSS2_RC
ifapi_calculate_policy_authorize(
    TPMS_POLICYAUTHORIZE *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;

    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.");

    r = calculate_policy_key_param(TPM2_CC_PolicyAuthorize,
                                   &policy->keyName,
                                   &policy->policyRef, hash_size,
                                   current_hash_alg,
                                   &current_digest->digests[digest_idx].digest);
    goto_if_error(r, "crypto hash start", cleanup);

cleanup:
    return r;
}

/** Calculate a policy for adding secret-based authorization.
 *
 * During execution proving the knowledge of the secrect auth value of a certain
 * object is required. The name of this object and a policy reference is used
 * for policy calculation.
 * Based on the command code, the object name and a policy reference the new
 * policy digest is computed by the function calculate_policy_key_param().
 *
 * @param[in] policy The policy with the object name of the object to be
 *            authorized  and the policy reference.
 * @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_GENERAL_FAILURE if an internal error occurred.
 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
 * @retval TSS2_FAPI_RC_MEMORY if not enough memory can be allocated.
 */
TSS2_RC
ifapi_calculate_policy_secret(
    TPMS_POLICYSECRET *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;

    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.");

    /* Update the policy */
    r = calculate_policy_key_param(TPM2_CC_PolicySecret,
                                   (TPM2B_NAME *)&policy->objectName,
                                   &policy->policyRef, hash_size,
                                   current_hash_alg,
                                   &current_digest->digests[digest_idx].digest);
    goto_if_error(r, "crypto hash start", cleanup);

cleanup:
    return r;
}

/** Calculate a policy for for comparing current TPM timers with the policy.
 *
 * The timer value and the operation for comparison defined in the policy will
 * bu used to update the policy digest.
 * The offset which is supported by the TPM policy for FAPI will be 0.
 *
 * @param[in] policy The policy with the timer value and the operation for
 *            comparison.
 * @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_GENERAL_FAILURE if an internal error occurred.
 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
 * @retval TSS2_FAPI_RC_MEMORY if not enough memory can be allocated.
 */
TSS2_RC
ifapi_calculate_policy_counter_timer(
    TPMS_POLICYCOUNTERTIMER *policy,
    TPML_DIGEST_VALUES *current_digest,
    TPMI_ALG_HASH current_hash_alg)
{
    TSS2_RC r = TSS2_RC_SUCCESS;
    IFAPI_CRYPTO_CONTEXT_BLOB *cryptoContext = NULL;
    size_t digest_idx;
    size_t hash_size;
    TPM2B_DIGEST counter_timer_hash;

    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.");

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

    /* Compute a has value from the offset, the timer value and the operation. */
    HASH_UPDATE_BUFFER(cryptoContext, &policy->operandB.buffer[0],
                       policy->operandB.size, r, cleanup);
    HASH_UPDATE(cryptoContext, UINT16, policy->offset, r, cleanup);
    HASH_UPDATE(cryptoContext, UINT16, policy->operation, r, cleanup);

    r = ifapi_crypto_hash_finish(&cryptoContext,
                                 (uint8_t *) &counter_timer_hash.buffer[0], &hash_size);
    return_if_error(r, "crypto hash finish");

    /* Extend the policy digest from the hash value computed above and the
       command code. */
    r = ifapi_crypto_hash_start(&cryptoContext, current_hash_alg);
    return_if_error(r, "crypto hash start");

    HASH_UPDATE_BUFFER(cryptoContext,
                       &current_digest->digests[digest_idx].digest, hash_size,
                       r, cleanup);
    HASH_UPDATE(cryptoContext, TPM2_CC, TPM2_CC_PolicyCounterTimer, r, cleanup);
    HASH_UPDATE_BUFFER(cryptoContext, &counter_timer_hash.buffer[0],
                       hash_size, r, cleanup);
    r = ifapi_crypto_hash_finish(&cryptoContext,
                                 (uint8_t *) &current_digest->digests[digest_idx].digest,
                                 &hash_size);
cleanup:
    if (cryptoContext)
        ifapi_crypto_hash_abort(&cryptoContext);
    return r;
}

/** Update policy if only the command codes are used.
 *
 * Some simple policies use onle one or two command codes for policy calculation.
 *
 * @param[in] command_code1 The first command code for policy extension.
 *            Can be NULL.
 * @param[in] command_code2 The second command code for policy extension.
 *            Can be NULL.
 * @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_GENERAL_FAILURE if an internal error occurred.
 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
 * @retval TSS2_FAPI_RC_MEMORY if not enough memory can be allocated.
 */
TSS2_RC
ifapi_calculate_simple_policy(
    TPM2_CC command_code1,
    TPM2_CC command_code2,
    TPML_DIGEST_VALUES *current_digest,
    TPMI_ALG_HASH current_hash_alg)
{
    TSS2_RC r = TSS2_RC_SUCCESS;
    IFAPI_CRYPTO_CONTEXT_BLOB *cryptoContext = NULL;
    size_t digest_idx;
    size_t hash_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.");

    /* Update the policy */
    r = ifapi_crypto_hash_start(&cryptoContext, current_hash_alg);
    return_if_error(r, "crypto hash start");

    HASH_UPDATE_BUFFER(cryptoContext,
                       &current_digest->digests[digest_idx].digest, hash_size,
                       r, cleanup);
    if (command_code1) {
        HASH_UPDATE(cryptoContext, TPM2_CC, command_code1, r, cleanup);
    }
    if (command_code2) {
        HASH_UPDATE(cryptoContext, TPM2_CC, command_code2, r, cleanup);
    }
    r = ifapi_crypto_hash_finish(&cryptoContext,
                                 (uint8_t *) &current_digest->digests[digest_idx].digest,
                                 &hash_size);

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

/** Update policy with command code policy physical presence.
 *
 * The policy will be updated with the function ifapi_calculate_simple_policy()
 *
 * @param[in] policy The policy physical presence.
 * @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_GENERAL_FAILURE if an internal error occurred.
 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
 * @retval TSS2_FAPI_RC_MEMORY if not enough memory can be allocated.
 */
TSS2_RC
ifapi_calculate_policy_physical_presence(
    TPMS_POLICYPHYSICALPRESENCE *policy,
    TPML_DIGEST_VALUES *current_digest,
    TPMI_ALG_HASH current_hash_alg)
{
    TSS2_RC r = TSS2_RC_SUCCESS;
    (void)policy;

    LOG_DEBUG("call");

    r = ifapi_calculate_simple_policy(TPM2_CC_PolicyPhysicalPresence, 0,
            current_digest, current_hash_alg);
    return_if_error(r, "Calculate policy for command code.");

    return r;
}

/** Update policy with command code of policy auth value.
 *
 * The policy will be updated with the function ifapi_calculate_simple_policy()
 *
 * @param[in] policy The policy auth value.
 * @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_GENERAL_FAILURE if an internal error occurred.
 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
 * @retval TSS2_FAPI_RC_MEMORY if not enough memory can be allocated.
 */
TSS2_RC
ifapi_calculate_policy_auth_value(
    TPMS_POLICYAUTHVALUE *policy,
    TPML_DIGEST_VALUES *current_digest,
    TPMI_ALG_HASH current_hash_alg)
{
    TSS2_RC r = TSS2_RC_SUCCESS;
    (void)policy;

    LOG_DEBUG("call");

    r = ifapi_calculate_simple_policy(TPM2_CC_PolicyAuthValue, 0,
            current_digest, current_hash_alg);
    return_if_error(r, "Calculate policy auth value.");

    return r;
}

/** Update policy with the command code of policy password.
 *
 * The policy will be updated with the function ifapi_calculate_simple_policy()
 *
 * @param[in] policy The policy password.
 * @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_GENERAL_FAILURE if an internal error occurred.
 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
 * @retval TSS2_FAPI_RC_MEMORY if not enough memory can be allocated.
 */
TSS2_RC
ifapi_calculate_policy_password(
    TPMS_POLICYPASSWORD *policy,
    TPML_DIGEST_VALUES *current_digest,
    TPMI_ALG_HASH current_hash_alg)
{
    TSS2_RC r = TSS2_RC_SUCCESS;
    (void)policy;

    LOG_DEBUG("call");

    r = ifapi_calculate_simple_policy(TPM2_CC_PolicyAuthValue, 0,
            current_digest, current_hash_alg);
    return_if_error(r, "Calculate policy password.");

    return r;
}

/** Update policy command code with a command code defined in the policy.
 *
 * For the update two command codes will be used. The command code of
 * policy command code and the passed command code.
 * The policy will be updated with the function ifapi_calculate_simple_policy()
 *
 * @param[in] policy The policy command code with the second command code.
 * @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_GENERAL_FAILURE if an internal error occurred.
 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
 * @retval TSS2_FAPI_RC_MEMORY if not enough memory can be allocated.
 */
TSS2_RC
ifapi_calculate_policy_command_code(
    TPMS_POLICYCOMMANDCODE *policy,
    TPML_DIGEST_VALUES *current_digest,
    TPMI_ALG_HASH current_hash_alg)
{
    TSS2_RC r = TSS2_RC_SUCCESS;

    LOG_DEBUG("call");

    r = ifapi_calculate_simple_policy(TPM2_CC_PolicyCommandCode, policy->code,
            current_digest, current_hash_alg);
    return_if_error(r, "Calculate policy for command code.");

    return r;
}

/** Compute policy if only a digest and a command code are needed for extension.
 *
 * @param[in] digest the digest which will be used for policy extension.
 * @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.
 * @param[in] command_code The compute of the command which did compute the digest.
 *
 * @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_GENERAL_FAILURE if an internal error occurred.
 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
 * @retval TSS2_FAPI_RC_MEMORY if not enough memory can be allocated.
 */
TSS2_RC
ifapi_calculate_policy_digest_hash(
    TPM2B_DIGEST *digest,
    TPML_DIGEST_VALUES *current_digest,
    TPMI_ALG_HASH current_hash_alg,
    TPM2_CC command_code)
{
    TSS2_RC r = TSS2_RC_SUCCESS;
    IFAPI_CRYPTO_CONTEXT_BLOB *cryptoContext = NULL;
    size_t digest_idx;
    size_t hash_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.");

    /* Update the policy. */
    r = ifapi_crypto_hash_start(&cryptoContext, current_hash_alg);
    return_if_error(r, "crypto hash start");

    HASH_UPDATE_BUFFER(cryptoContext,
                       &current_digest->digests[digest_idx].digest, hash_size,
                       r, cleanup);
    HASH_UPDATE(cryptoContext, TPM2_CC, command_code, r, cleanup);
    HASH_UPDATE_BUFFER(cryptoContext, &digest->buffer[0],
                       digest->size, r, cleanup);
    r = ifapi_crypto_hash_finish(&cryptoContext,
                                 (uint8_t *) &current_digest->digests[digest_idx].digest,
                                 &hash_size);
cleanup:
    if (cryptoContext)
        ifapi_crypto_hash_abort(&cryptoContext);
    return r;
}

/** Compute policy bound to a specific set of TPM entities.
 *
 * The policy digest will be updated with the function
 * ifapi_calculate_policy_digest_hash() which will add the hash of the
 * entity name list.
 *
 * @param[in] policy The policy with the list of entity names.
 * @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_GENERAL_FAILURE if an internal error occurred.
 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
 * @retval TSS2_FAPI_RC_MEMORY if not enough memory can be allocated.
 */
TSS2_RC
ifapi_calculate_policy_name_hash(
    TPMS_POLICYNAMEHASH *policy,
    TPML_DIGEST_VALUES *current_digest,
    TPMI_ALG_HASH current_hash_alg)
{
    TSS2_RC r = TSS2_RC_SUCCESS;
    IFAPI_CRYPTO_CONTEXT_BLOB *cryptoContext = NULL;
    size_t hash_size;
    size_t i;

    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 = ifapi_crypto_hash_start(&cryptoContext, current_hash_alg);
    return_if_error(r, "crypto hash start");

    /* Compute name hash from the list of object names */
    for (i = 0; i <= policy->count; i++) {
        HASH_UPDATE_BUFFER(cryptoContext, &policy->objectNames[i].name[0],
                           policy->objectNames[i].size, r,
                           cleanup);
    }
    r = ifapi_crypto_hash_finish(&cryptoContext,
                                 (uint8_t *) &policy->nameHash.buffer[0],
                                 &hash_size);
    return_if_error(r, "crypto hash finish");

    policy->nameHash.size = hash_size;

    /* Update the policy with the computed hash value of the name list and
       the command code. */
    r = ifapi_calculate_policy_digest_hash(&policy->nameHash,
                                           current_digest,
                                           current_hash_alg, TPM2_CC_PolicyNameHash);
    return_if_error(r, "Calculate digest hash for policy");

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

/** Compute policy bound to a specific command and command parameters.
 *
 * The cp hash value and the command code will be updated by the
 * function ifapi_calculate_policy_digest_hash().
 *
 * @param[in] policy The policy with the cp hash value.
 * @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_GENERAL_FAILURE if an internal error occurred.
 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
 * @retval TSS2_FAPI_RC_MEMORY if not enough memory can be allocated.
 */
TSS2_RC
ifapi_calculate_policy_cp_hash(
    TPMS_POLICYCPHASH *policy,
    TPML_DIGEST_VALUES *current_digest,
    TPMI_ALG_HASH current_hash_alg)
{
    TSS2_RC r = TSS2_RC_SUCCESS;

    LOG_DEBUG("call");

    r = ifapi_calculate_policy_digest_hash(&policy->cpHash,
                                           current_digest, current_hash_alg,
                                           TPM2_CC_PolicyCpHash);
    return_if_error(r, "Calculate digest hash for policy");

    return r;
}

/** Compute policy which limits authorization to a specific locality.
 *
 * @param[in] policy The policy with the locality.
 * @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_GENERAL_FAILURE if an internal error occurred.
 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
 * @retval TSS2_FAPI_RC_MEMORY if not enough memory can be allocated.
 */
TSS2_RC
ifapi_calculate_policy_locality(
    TPMS_POLICYLOCALITY *policy,
    TPML_DIGEST_VALUES *current_digest,
    TPMI_ALG_HASH current_hash_alg)
{
    TSS2_RC r = TSS2_RC_SUCCESS;
    IFAPI_CRYPTO_CONTEXT_BLOB *cryptoContext = NULL;
    size_t digest_idx;
    size_t hash_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.");

    /* Update the policy */
    r = ifapi_crypto_hash_start(&cryptoContext, current_hash_alg);
    return_if_error(r, "crypto hash start");

    HASH_UPDATE_BUFFER(cryptoContext,
                       &current_digest->digests[digest_idx].digest, hash_size,
                       r, cleanup);
    HASH_UPDATE(cryptoContext, TPM2_CC, TPM2_CC_PolicyLocality, r, cleanup);
    HASH_UPDATE(cryptoContext, BYTE, policy->locality, r, cleanup);
    r = ifapi_crypto_hash_finish(&cryptoContext,
                                 (uint8_t *) & current_digest->
                                 digests[digest_idx].digest, &hash_size);

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

/** Compute policy bound to bound to the TPMA_NV_WRITTEN attributes.
 *
 * The expected value of the NV written attribute is part of the policy.
 *
 * @param[in] policy The policy with the expected attribute value.
 * @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_GENERAL_FAILURE if an internal error occurred.
 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
 * @retval TSS2_FAPI_RC_MEMORY if not enough memory can be allocated.
 */
TSS2_RC
ifapi_calculate_policy_nv_written(
    TPMS_POLICYNVWRITTEN *policy,
    TPML_DIGEST_VALUES *current_digest,
    TPMI_ALG_HASH current_hash_alg)
{
    TSS2_RC r = TSS2_RC_SUCCESS;
    IFAPI_CRYPTO_CONTEXT_BLOB *cryptoContext = NULL;
    size_t digest_idx;
    size_t hash_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.");

    /* Update the policy */
    r = ifapi_crypto_hash_start(&cryptoContext, current_hash_alg);
    return_if_error(r, "crypto hash start");

    HASH_UPDATE_BUFFER(cryptoContext,
                       &current_digest->digests[digest_idx].digest, hash_size,
                       r, cleanup);
    HASH_UPDATE(cryptoContext, TPM2_CC, TPM2_CC_PolicyNvWritten, r, cleanup);
    /* Update the expected attribute value. */
    HASH_UPDATE(cryptoContext, BYTE, policy->writtenSet, r, cleanup);
    r = ifapi_crypto_hash_finish(&cryptoContext,
                                 (uint8_t *) & current_digest->
                                 digests[digest_idx].digest, &hash_size);

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

/** Compute policy bound to the content of an NV index.
 *
 * The value used for comparison, the compare operation and an
 * offset for the NV index are part of the policy.
 *
 * @param[in] policy The policy with the expected values used for comparison.
 * @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_GENERAL_FAILURE if an internal error occurred.
 * @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_BAD_VALUE if an invalid value was passed into
 *         the function.
 */
TSS2_RC
ifapi_calculate_policy_nv(
    TPMS_POLICYNV *policy,
    TPML_DIGEST_VALUES *current_digest,
    TPMI_ALG_HASH current_hash_alg)
{
    TSS2_RC r = TSS2_RC_SUCCESS;
    IFAPI_CRYPTO_CONTEXT_BLOB *cryptoContext = NULL;
    TPM2B_NAME nv_name;
    size_t hash_size;
    TPM2B_DIGEST nv_hash;
    size_t digest_idx;

    LOG_DEBUG("call");

    memset(&nv_name, 0, sizeof(TPM2B_NAME));

    /* Written flag has to be set for policy calculation, because during
       policy execution it will be set. */
    policy->nvPublic.nvPublic.attributes |= TPMA_NV_WRITTEN;

    /* Compute NV name from public info */

    r = ifapi_nv_get_name(&policy->nvPublic, &nv_name);
    return_if_error(r, "Compute NV name");

    /* 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.");

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

    /* Compute the hash for the compare operation. */
    HASH_UPDATE_BUFFER(cryptoContext, &policy->operandB.buffer[0],
                       policy->operandB.size, r, cleanup);
    HASH_UPDATE(cryptoContext, UINT16, policy->offset, r, cleanup);
    HASH_UPDATE(cryptoContext, UINT16, policy->operation, r, cleanup);
    r = ifapi_crypto_hash_finish(&cryptoContext,
                                 (uint8_t *) &nv_hash.buffer[0], &hash_size);
    return_if_error(r, "crypto hash finish");

    nv_hash.size = hash_size;

    /* Update the policy with the hash of the compare operation and the NV name. */
    r = ifapi_crypto_hash_start(&cryptoContext, current_hash_alg);
    return_if_error(r, "crypto hash start");

    HASH_UPDATE_BUFFER(cryptoContext,
                       &current_digest->digests[digest_idx].digest, hash_size,
                       r, cleanup);
    HASH_UPDATE(cryptoContext, TPM2_CC, TPM2_CC_PolicyNV, r, cleanup);
    HASH_UPDATE_BUFFER(cryptoContext, &nv_hash.buffer[0], nv_hash.size, r, cleanup)
    HASH_UPDATE_BUFFER(cryptoContext, &nv_name.name[0], nv_name.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");

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

/** Compute a list of policies to enable authorization options.
 *
 * First the policy digest will be computed for every branch.
 * After that the policy digest will be reset to zero and extended by the
 * list of computed policy digests of the branches.
 *
 * @param[in] policyOr The policy with the possible policy branches.
 * @param[in,out] current_digest The digest list which has to be updated.
 * @param[in] hash_alg The hash algorithm used for the policy computation.
 * @param[in] hash_size The size of the policy digest.
 * @param[in] digest_idx The index of the current policy in the passed digest list.
 *
 * @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_GENERAL_FAILURE if an internal error occurred.
 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
 * @retval TSS2_FAPI_RC_MEMORY if not enough memory can be allocated.
 */
TSS2_RC
ifapi_calculate_policy_or(
    TPMS_POLICYOR *policyOr,
    TPML_DIGEST_VALUES *current_digest,
    TPMI_ALG_HASH hash_alg,
    size_t hash_size,
    size_t digest_idx)
{
    size_t i;
    TSS2_RC r = TSS2_RC_SUCCESS;
    IFAPI_CRYPTO_CONTEXT_BLOB *cryptoContext = NULL;

    for (i = 0; i < policyOr->branches->count; i++) {
        /* Compute the policy digest for every branch. */
        copy_policy_digest(&policyOr->branches->authorizations[i].policyDigests,
                           current_digest, digest_idx, hash_size,
                           "Copy or digest");

        r = ifapi_calculate_policy(policyOr->branches->authorizations[i].policy,
                                   &policyOr->branches->authorizations[i].
                                   policyDigests, hash_alg, hash_size,
                                   digest_idx);
        log_policy_digest(&policyOr->branches->authorizations[i].policyDigests,
                          digest_idx, hash_size, "Branch digest");

        return_if_error(r, "Compute policy.");
    }
    /* Reset the or policy digest because the digest is included in all sub policies */
    memset(&current_digest->digests[digest_idx], 0, hash_size);
    r = ifapi_crypto_hash_start(&cryptoContext, hash_alg);
    return_if_error(r, "crypto hash start");
    r = ifapi_crypto_hash_update(cryptoContext, (const uint8_t *)
                                 &current_digest->digests[digest_idx].digest,
                                 hash_size);
    goto_if_error(r, "crypto hash update", cleanup);

    /* Start with the update of the reset digest. */
    uint8_t buffer[sizeof(TPM2_CC)];
    size_t offset = 0;
    r = Tss2_MU_TPM2_CC_Marshal(TPM2_CC_PolicyOR,
                                &buffer[0], sizeof(TPM2_CC), &offset);
    goto_if_error(r, "Marshal cc", cleanup);

    r = ifapi_crypto_hash_update(cryptoContext,
                                 (const uint8_t *)&buffer[0], sizeof(TPM2_CC));
    goto_if_error(r, "crypto hash update", cleanup);

    /* Update the digest with the complete list of computed digests of the branches. */
    for (i = 0; i < policyOr->branches->count; i++) {
        r = ifapi_crypto_hash_update(cryptoContext, (const uint8_t *)
                                     &policyOr->branches->authorizations[i]
                                     .policyDigests.digests[digest_idx].digest,
                                     hash_size);
        log_policy_digest(&policyOr->branches->authorizations[i].policyDigests,
                          digest_idx, hash_size, "Or branch");
        current_digest->count =
            policyOr->branches->authorizations[i].policyDigests.count;
        goto_if_error(r, "crypto hash update", cleanup);
    }
    current_digest->digests[digest_idx].hashAlg = hash_alg;
    r = ifapi_crypto_hash_finish(&cryptoContext,
                                 (uint8_t *) & current_digest->
                                 digests[digest_idx].digest, &hash_size);
    log_policy_digest(current_digest, digest_idx, hash_size, "Final or digest");
    goto_if_error(r, "crypto hash finish", cleanup);

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
 * policy digest will describe the sequential execution of the policy list.
 *
 * @param[in] policy The policy with the policy list.
 * @param[in,out] policyDigests The digest list which has to be updated.
 * @param[in] hash_alg The hash algorithm used for the policy computation.
 * @param[in] hash_size The size of the policy digest.
 * @param[in] digest_idx The index of the current policy in the passed digest list.
 *
 * @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_GENERAL_FAILURE if an internal error occurred.
 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
 * @retval TSS2_FAPI_RC_MEMORY if not enough memory can be allocated.
 */
TSS2_RC
ifapi_calculate_policy(
    TPML_POLICYELEMENTS *policy,
    TPML_DIGEST_VALUES *policyDigests,
    TPMI_ALG_HASH hash_alg,
    size_t hash_size,
    size_t digest_idx)
{
    size_t i;
    TSS2_RC r = TSS2_RC_SUCCESS;

    for (i = 0; i < policy->count; i++) {

        copy_policy_digest(&policy->elements[i].policyDigests,
                           policyDigests, digest_idx, hash_size,
                           "Copy policy digest (to)");

        switch (policy->elements[i].type) {

        case POLICYPCR:
            r = ifapi_compute_policy_pcr(&policy->elements[i].element.PolicyPCR,
                                         &policy->elements[i].policyDigests,
                                         hash_alg);
            return_if_error(r, "Compute policy pcr");
            break;

        case POLICYSIGNED:
            r = ifapi_calculate_policy_signed(&policy->elements[i].element.
                                              PolicySigned,
                                              &policy->elements[i].
                                              policyDigests, hash_alg);
            return_if_error(r, "Compute policy nv");

            break;

        case POLICYDUPLICATIONSELECT:
            r = ifapi_calculate_policy_duplicate(&policy->elements[i].element.
                                                 PolicyDuplicationSelect,
                                                 &policy->elements[i].
                                                 policyDigests, hash_alg);
            return_if_error(r, "Compute policy duplication select");

            break;

        case POLICYAUTHORIZENV:
            r = ifapi_calculate_policy_authorize_nv(&policy->elements[i].
                                                    element.PolicyAuthorizeNv,
                                                    &policy->elements[i].
                                                    policyDigests, hash_alg);
            return_if_error(r, "Compute policy authorizeg");

            break;

        case POLICYAUTHORIZE:
            r = ifapi_calculate_policy_authorize(&policy->elements[i].element.
                                                 PolicyAuthorize,
                                                 &policy->elements[i].
                                                 policyDigests, hash_alg);
            return_if_error(r, "Compute policy authorizeg");

            break;

        case POLICYSECRET:
            r = ifapi_calculate_policy_secret(&policy->elements[i].element.
                                              PolicySecret,
                                              &policy->elements[i].
                                              policyDigests, hash_alg);
            return_if_error(r, "Compute policy nv");

            break;

        case POLICYOR:
            r = ifapi_calculate_policy_or(&policy->elements[i].element.PolicyOr,
                                          &policy->elements[i].policyDigests,
                                          hash_alg, hash_size, digest_idx);
            return_if_error(r, "Compute policy or");

            break;

        case POLICYNV:
            r = ifapi_calculate_policy_nv(&policy->elements[i].element.PolicyNV,
                                          &policy->elements[i].policyDigests,
                                          hash_alg);
            return_if_error(r, "Compute policy nv");

            break;

        case POLICYNVWRITTEN:
            r = ifapi_calculate_policy_nv_written(&policy->elements[i].element.
                                                  PolicyNvWritten,
                                                  &policy->elements[i].
                                                  policyDigests, hash_alg);
            return_if_error(r, "Compute policy nv written");
            break;

        case POLICYCOUNTERTIMER:
            r = ifapi_calculate_policy_counter_timer(
                    &policy->elements[i].element.PolicyCounterTimer,
                    &policy->elements[i].policyDigests, hash_alg);
            return_if_error(r, "Compute policy counter timer");
            break;

        case POLICYPHYSICALPRESENCE:
            r = ifapi_calculate_policy_physical_presence(
                    &policy->elements[i].element.PolicyPhysicalPresence,
                    &policy->elements[i].policyDigests, hash_alg);
            return_if_error(r, "Compute policy physical presence");
            break;

        case POLICYAUTHVALUE:
            r = ifapi_calculate_policy_auth_value(&policy->elements[i].element.PolicyAuthValue,
                                                  &policy->elements[i].policyDigests, hash_alg);
            return_if_error(r, "Compute policy auth value");
            break;

        case POLICYPASSWORD:
            r = ifapi_calculate_policy_password(&policy->elements[i].element.PolicyPassword,
                                                &policy->elements[i].policyDigests, hash_alg);
            return_if_error(r, "Compute policy password");
            break;

        case POLICYCOMMANDCODE:
            r = ifapi_calculate_policy_command_code(&policy->elements[i].element.PolicyCommandCode,
                                                    &policy->elements[i].policyDigests, hash_alg);
            return_if_error(r, "Compute policy physical presence");
            break;

        case POLICYNAMEHASH:
            r = ifapi_calculate_policy_name_hash(&policy->elements[i].element.PolicyNameHash,
                                                 &policy->elements[i].policyDigests, hash_alg);
            return_if_error(r, "Compute policy  name hash");
            break;

        case POLICYCPHASH:
            r = ifapi_calculate_policy_cp_hash(&policy->elements[i].element.PolicyCpHash,
                                               &policy->elements[i].policyDigests, hash_alg);
            return_if_error(r, "Compute policy cp hash");
            break;

        case POLICYLOCALITY:
            r = ifapi_calculate_policy_locality(&policy->elements[i].element.PolicyLocality,
                                                &policy->elements[i].policyDigests, hash_alg);
            return_if_error(r, "Compute policy locality");
            break;

        case POLICYACTION:
            /* This does not alter the policyDigest */
            break;

        default:
            return_error(TSS2_FAPI_RC_BAD_VALUE,
                         "Policy not implemented");
        }

        copy_policy_digest(policyDigests, &policy->elements[i].policyDigests,
                           digest_idx, hash_size, "Copy policy digest (from)");
    }
    return r;
}
