/* 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 <stdio.h>
#include <string.h>
#include <stdarg.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <ctype.h>
#include <dirent.h>

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

/** State machine for flushing objects.
 *
 * @param[in] context The FAPI_CONTEXT.
 * @param[in] handle of the object to be flushed.
 *
 * @retval TSS2_RC_SUCCESS on success.
 * @retval TSS2_ESYS_RC_* possible error codes of ESAPI.
 * @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.
 */
TSS2_RC
ifapi_flush_object(FAPI_CONTEXT *context, ESYS_TR handle)
{
    TSS2_RC r = TSS2_RC_SUCCESS;

    if (handle == ESYS_TR_NONE)
        return r;

    switch (context->flush_object_state) {
    statecase(context->flush_object_state, FLUSH_INIT);
        r = Esys_FlushContext_Async(context->esys, handle);
        return_if_error(r, "Flush Object");
        fallthrough;

    statecase(context->flush_object_state, WAIT_FOR_FLUSH);
        r = Esys_FlushContext_Finish(context->esys);
        if (base_rc(r) == TSS2_BASE_RC_TRY_AGAIN)
            return TSS2_FAPI_RC_TRY_AGAIN;

        return_if_error(r, "FlushContext");

        context->flush_object_state = FLUSH_INIT;
        return TSS2_RC_SUCCESS;

    statecasedefault(context->flush_object_state);
    }
}

/** Preparation for getting a session handle.
 *
 * The corresponding async call be executed and a session secret for encryption
 * TPM2B parameters will be created.
 *
 * @param[in] esys The ESYS_CONTEXT.
 * @param[in] saltkey The key which will be used for the encryption of the session
 *            secret.
 * @param[in] profile The FAPI profile will be used to adjust the sessions symmetric
 *            parameters.
 * @param[in] hashAlg The hash algorithm used for the session.
 *
 * @retval TSS2_RC_SUCCESS on success.
 * @retval TSS2_ESYS_RC_* possible error codes of ESAPI.
 */
TSS2_RC
ifapi_get_session_async(ESYS_CONTEXT *esys, ESYS_TR saltkey, const IFAPI_PROFILE *profile,
                        TPMI_ALG_HASH hashAlg)
{
    TSS2_RC r;

    r = Esys_StartAuthSession_Async(esys, saltkey,
                                    ESYS_TR_NONE,
                                    ESYS_TR_NONE, ESYS_TR_NONE, ESYS_TR_NONE,
                                    NULL,
                                    TPM2_SE_HMAC, &profile->session_symmetric,
                                    hashAlg);
    return_if_error(r, "Creating session.");

    return TSS2_RC_SUCCESS;
}

/**  Call for getting a session handle and adjust session parameters.
 *
 * @param[in] esys The ESYS_CONTEXT.
 * @param[out] session The session handle.
 * @param[in] flags The flags to adjust the session attributes.
 *
 * @retval TSS2_RC_SUCCESS on success.
 * @retval TSS2_ESYS_RC_* possible error codes of ESAPI.
 */
TSS2_RC
ifapi_get_session_finish(ESYS_CONTEXT *esys, ESYS_TR *session,
                         TPMA_SESSION flags)
{
    TSS2_RC r;
    TPMA_SESSION sessionAttributes = 0;

    /* Check whether authorization callback is defined */

    r = Esys_StartAuthSession_Finish(esys, session);
    if (r != TSS2_RC_SUCCESS)
        return r;

    sessionAttributes |= flags;
    sessionAttributes |= TPMA_SESSION_CONTINUESESSION;

    r = Esys_TRSess_SetAttributes(esys, *session, sessionAttributes,
                                  0xff);
    return_if_error(r, "Set session attributes.");

    return TSS2_RC_SUCCESS;
}

/** Get the digest size of the policy of a FAPI object.
 *
 * @param[in] object The object with the correspodning policy.
 *
 * @retval The size of policy digest.
 * @retval 0 if The object does not have a policy.
 */
static size_t
policy_digest_size(IFAPI_OBJECT *object)
{
    switch (object->objectType) {
    case IFAPI_KEY_OBJ:
        return object->misc.key.public.publicArea.authPolicy.size;
    case IFAPI_NV_OBJ:
        return object->misc.nv.public.nvPublic.authPolicy.size;
    case IFAPI_HIERARCHY_OBJ:
        return object->misc.hierarchy.authPolicy.size;
    default:
        return 0;
    }
}

/** Add a object together with size as first element to a linked list.
 *
 * This function can e.g. used to add byte arrays together with their size
 * to a linked list.
 *
 * @param[in] object The object to be added.
 * @param[in] size The size of the object to be added.
 * @param[in,out] object_list The linked list to be extended.
 *
 * @retval TSS2_RC_SUCCESS if the object was added.
 * @retval TSS2_FAPI_RC_MEMORY If memory for the list extension cannot
 *         be allocated.
 */
static TSS2_RC
push_object_with_size_to_list(void *object, size_t size, NODE_OBJECT_T **object_list)
{
    TSS2_RC r;
    r = push_object_to_list(object, object_list);
    return_if_error(r, "Push object with size.");

    (*object_list)->size = size;

    return TSS2_RC_SUCCESS;
}

/** Initialize and expand the linked list representing a FAPI key path.
 *
 * From a passed key path the explicit key path will be determined. The
 * profile and the hierarchy will be added if necessary and the extension
 * is possible.
 *
 * @param[in]  context_profile The profile used for extension of no profile is
 *             part of the path.
 * @param[in]  ipath The implicit pathname which has to be extended.
 * @param[out] list_node1 The linked list for the passed key path without
 *             extensions.
 * @param[out] current_list_node The current node in the list list_node1,
 *             which represent the tail not processed.
 * @param[out] result The part of the new list which had been extended
 *             without the tail not processed.
 *
 * @retval TSS2_RC_SUCCESS: If the initialization was successful.
 * @retval TSS2_FAPI_RC_BAD_VALUE If an invalid path was passed.
 * @retval TSS2_FAPI_RC_MEMORY: if not enough memory can be allocated.
 * @retval TSS2_FAPI_RC_BAD_PATH if the path is used in inappropriate context
 *         or contains illegal characters.
 */
static TSS2_RC
init_explicit_key_path(
    const char *context_profile,
    const char *ipath,
    NODE_STR_T **list_node1,
    NODE_STR_T **current_list_node,
    NODE_STR_T **result)
{
    *list_node1 = split_string(ipath, IFAPI_FILE_DELIM);
    NODE_STR_T *list_node = *list_node1;
    char const *profile;
    char *hierarchy;
    TSS2_RC r = TSS2_RC_SUCCESS;

    *result = NULL;
    if (list_node == NULL) {
        LOG_ERROR("Invalid path");
        free_string_list(*list_node1);
        return TSS2_FAPI_RC_BAD_VALUE;
    }

    /* Processing of the profile. */
    if (strncmp("P_", list_node->str, 2) == 0) {
        profile = list_node->str;
        list_node = list_node->next;
    } else {
        profile = context_profile;
    }
    /* Create the initial node of the linked list. */
    *result = init_string_list(profile);
    if (*result == NULL) {
        free_string_list(*list_node1);
        LOG_ERROR("Out of memory");
        return TSS2_FAPI_RC_MEMORY;
    }
    if (list_node == NULL) {
        /* Storage hierarchy will be used as default. */
        hierarchy = "HS";
    } else {
        if (strcmp(list_node->str, "HN") == 0) {
            hierarchy = list_node->str;
            list_node = list_node->next;
        } else if (strcmp(list_node->str, "HS") == 0 ||
                   strcmp(list_node->str, "HE") == 0 ||
                   strcmp(list_node->str, "HN") == 0) {
            hierarchy = list_node->str;
            list_node = list_node->next;
        } else if (strcmp(list_node->str, "EK") == 0) {
            /* The hierarchy for an endorsement key will be added. */
            hierarchy = "HE";
        } else if (list_node->str != NULL &&
                   strcmp(list_node->str, "SRK") == 0) {
            /* The storage hierachy will be added. */
            hierarchy = "HS";
        } else {
            LOG_ERROR("Hierarchy cannot be determined.");
            r = TSS2_FAPI_RC_BAD_PATH;
            goto error;
        }
    }
    /* Add the used hierarchy to the linked list. */
    if (!add_string_to_list(*result, hierarchy)) {
        LOG_ERROR("Out of memory");
        r = TSS2_FAPI_RC_MEMORY;
        goto error;
    }
    if (list_node == NULL) {
        goto_error(r, TSS2_FAPI_RC_BAD_PATH, "Explicit path can't be determined.",
                   error);
    }

    /* Add the primary directory to the linked list. */
    if (!add_string_to_list(*result, list_node->str)) {
        LOG_ERROR("Out of memory");
        r = TSS2_FAPI_RC_MEMORY;
        goto error;
    }

    if (strcmp(hierarchy, "HS") == 0 && strcmp(list_node->str, "EK") == 0) {
        LOG_ERROR("Key EK cannot be create in the storage hierarchy.");
        r = TSS2_FAPI_RC_BAD_PATH;
        goto error;
    }

    if (strcmp(hierarchy, "HE") == 0 && strcmp(list_node->str, "SRK") == 0) {
        LOG_ERROR("Key EK cannot be create in the endorsement hierarchy.");
        r = TSS2_FAPI_RC_BAD_PATH;
        goto error;
    }

    if (strcmp(hierarchy, "HN") == 0 &&
        (strcmp(list_node->str, "SRK") == 0 || strcmp(list_node->str, "EK") == 0)) {
        LOG_ERROR("Key EK and SRK cannot be created in NULL hierarchy.");
        r = TSS2_FAPI_RC_BAD_PATH;
        goto error;
    }

    /* Return the rest of the path. */
    *current_list_node = list_node->next;
    return TSS2_RC_SUCCESS;

error:
    free_string_list(*result);
    *result = NULL;
    free_string_list(*list_node1);
    *list_node1 = NULL;
    return r;
}

/** Free first object of a linked list.
 *
 * Note: Referenced objects of the list have to be freed before.
 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
 */
static TSS2_RC
pop_object_from_list(FAPI_CONTEXT *context, NODE_OBJECT_T **object_list)
{
    return_if_null(*object_list, "Pop from list.", TSS2_FAPI_RC_BAD_REFERENCE);

    NODE_OBJECT_T *head = *object_list;
    NODE_OBJECT_T *next = head->next;
    *object_list = next;
    ifapi_free_object(context, (void *)&head->object);
    free(head);
    return TSS2_RC_SUCCESS;
}

/** Get relative path of a FAPI object.
 *
 * @param[in] object The internal FAPI object.
 *
 * @retval The relative path of the object.
 * @retval NULL if no path is available.
 */
const char *
ifapi_get_object_path(IFAPI_OBJECT *object)
{
    if (object->rel_path)
        return object->rel_path;

    /* For hierarchies the path might not be set during reading
       from keystore. */
    if (object->objectType == IFAPI_HIERARCHY_OBJ) {
        switch (object->handle) {
        case ESYS_TR_RH_NULL:
            return "/HN";
        case ESYS_TR_RH_OWNER:
            return "/HS";
        case ESYS_TR_RH_ENDORSEMENT:
            return "/HE";
        case ESYS_TR_RH_LOCKOUT:
            return  "/LOCKOUT";
        }
    }
    return NULL;
}

/** Set authorization value for a primary key to be created.
 *
 * The callback which provides the auth value must be defined.
 *
 * @param[in,out] context The FAPI_CONTEXT.
 * @param[in]     object The auth value will be assigned to this object.
 * @param[in,out] inSensitive The sensitive data to store the auth value.
 *
 * @retval TSS2_RC_SUCCESS on success.
 * @retval TSS2_FAPI_RC_AUTHORIZATION_UNKNOWN If the callback for getting
 *         the auth value is not defined.
 */
TSS2_RC
ifapi_set_auth_primary(
    FAPI_CONTEXT *context,
    IFAPI_OBJECT *object,
    TPMS_SENSITIVE_CREATE *inSensitive)
{
    TSS2_RC r;
    const char *auth = NULL;
    const char *obj_path;

    memset(inSensitive, 0, sizeof(TPMS_SENSITIVE_CREATE));

    if (!object->misc.key.with_auth) {
        return TSS2_RC_SUCCESS;
    }

    obj_path = ifapi_get_object_path(object);

    /* Check whether callback is defined. */
    if (context->callbacks.auth) {
        r = context->callbacks.auth(obj_path, object->misc.key.description,
                                    &auth, context->callbacks.authData);
        return_if_error(r, "AuthCallback");
        if (auth != NULL) {
            inSensitive->userAuth.size = strlen(auth);
            memcpy(&inSensitive->userAuth.buffer[0], auth,
                   inSensitive->userAuth.size);
        }
        return TSS2_RC_SUCCESS;
    }
    SAFE_FREE(auth);
    return_error( TSS2_FAPI_RC_AUTHORIZATION_UNKNOWN, "Authorization callback not defined.");
}

/** Set authorization value for a FAPI object.
 *
 * The callback which provides the auth value must be defined.
 *
 * @param[in,out] context The FAPI_CONTEXT.
 * @param[in]     auth_object The auth value will be assigned to this object.
 * @param[in]     description The description will be passed to the callback
 *                which delivers the auth value.
 *
 * @retval TSS2_RC_SUCCESS on success.
 * @retval TSS2_FAPI_RC_AUTHORIZATION_UNKNOWN If the callback for getting
 *         the auth value is not defined.
 */
TSS2_RC
ifapi_set_auth(
    FAPI_CONTEXT *context,
    IFAPI_OBJECT *auth_object,
    const char *description)
{
    TSS2_RC r;
    const char *auth = NULL;
    TPM2B_AUTH authValue = {.size = 0,.buffer = {0} };
    const char *obj_path;

    obj_path = ifapi_get_object_path(auth_object);

    /* Check whether callback is defined. */
    if (context->callbacks.auth) {
        r = context->callbacks.auth(obj_path, description, &auth,
                                    context->callbacks.authData);
        return_if_error(r, "policyAuthCallback");
        if (auth != NULL) {
            authValue.size = strlen(auth);
            memcpy(&authValue.buffer[0], auth, authValue.size);
        }

        /* Store auth value in the ESYS object. */
        r = Esys_TR_SetAuth(context->esys, auth_object->handle, &authValue);
        return_if_error(r, "Set auth value.");

        if (auth_object->objectType == IFAPI_HIERARCHY_OBJ)
            auth_object->misc.hierarchy.authorized = true;

        return TSS2_RC_SUCCESS;
    }
    SAFE_FREE(auth);
    return_error( TSS2_FAPI_RC_AUTHORIZATION_UNKNOWN, "Authorization callback not defined.");
}

/** Preparation for getting a free handle after a start handle number.
 *
 * @param[in] fctx The FAPI_CONTEXT.
 * @param[in] handle The start value for handle search.
 *
 * @retval TSS2_RC_SUCCESS on success.
 * @retval TSS2_ESYS_RC_* possible error codes of ESAPI.
 */
TSS2_RC
ifapi_get_free_handle_async(FAPI_CONTEXT *fctx, TPM2_HANDLE *handle)
{
    TSS2_RC r = Esys_GetCapability_Async(fctx->esys,
                                         ESYS_TR_NONE, ESYS_TR_NONE, ESYS_TR_NONE,
                                         TPM2_CAP_HANDLES, *handle, 1);
    return_if_error(r, "GetCapability");
    return r;
}

/** Execution of get capability until a free handle is found.
 *
 * The get capability method is called until a free handle is found
 * or the max number of trials passe to the function is exeeded.
 *
 * @param[in] fctx The FAPI_CONTEXT.
 * @param[out] handle The free handle.
 * @param[in] max The maximal number of trials.
 *
 * @retval TSS2_RC_SUCCESS on success.
 * @retval TSS2_FAPI_RC_NV_TOO_SMALL if too many NV handles are defined.
 * @retval TSS2_ESYS_RC_* possible error codes of ESAPI.
 * @retval TSS2_FAPI_RC_TRY_AGAIN if an I/O operation is not finished yet and
 *         this function needs to be called again.
 */
TSS2_RC
ifapi_get_free_handle_finish(FAPI_CONTEXT *fctx, TPM2_HANDLE *handle,
                             TPM2_HANDLE max)
{
    TPMI_YES_NO moreData;
    TPMS_CAPABILITY_DATA *capabilityData = NULL;
    TSS2_RC r = Esys_GetCapability_Finish(fctx->esys,
                                          &moreData, &capabilityData);

    if (base_rc(r) == TSS2_BASE_RC_TRY_AGAIN)
        return TSS2_FAPI_RC_TRY_AGAIN;

    return_if_error(r, "GetCapability");

    if (capabilityData->data.handles.count == 0 ||
            capabilityData->data.handles.handle[0] != *handle) {
        SAFE_FREE(capabilityData);
        return TSS2_RC_SUCCESS;
    }
    SAFE_FREE(capabilityData);
    *handle += 1;
    if (*handle > max) {
        return_error(TSS2_FAPI_RC_NV_TOO_SMALL, "No NV index free.");
    }

    r = ifapi_get_free_handle_async(fctx, handle);
    return_if_error(r, "GetCapability");

    return TSS2_FAPI_RC_TRY_AGAIN;
}

/** Create a linked list of directories in the key store.
 *
 * If the absolute path in key store is not defined the list will
 * be extended if possible.
 *
 * @param[out] keystore The used keystore.
 * @param[in] ipath The implicit pathname, which might be extended.
 * @param[out] The linked list of directories in the explicit pathname.
 *
 * @retval TSS2_RC_SUCCESS If the keystore can be initialized.
 * @retval TSS2_FAPI_RC_IO_ERROR If the user part of the keystore can't be
 *         initialized.
 * @retval TSS2_FAPI_RC_MEMORY if memory could not be allocated.
 * @retval TSS2_FAPI_RC_BAD_VALUE if an invalid value was passed into
 *         the function.
 * @retval TSS2_FAPI_RC_BAD_PATH if the path is used in inappropriate context
 *         or contains illegal characters.
 * @retval TSS2_FAPI_RC_PATH_NOT_FOUND if a FAPI object path was not found
 *         during authorization.
 */
static TSS2_RC
get_explicit_key_path(
    IFAPI_KEYSTORE *keystore,
    const char *ipath,
    NODE_STR_T **result)
{
    NODE_STR_T *list_node1 = NULL;
    NODE_STR_T *list_node = NULL;

    /* Extend the first part of the list if necessary. */
    TSS2_RC r = init_explicit_key_path(keystore->defaultprofile, ipath,
                                       &list_node1, &list_node, result);
    goto_if_error(r, "init_explicit_key_path", error);

    /* Extend the list with the tail of the initial unmodified list. */
    while (list_node != NULL) {
        if (!add_string_to_list(*result, list_node->str)) {
            LOG_ERROR("Out of memory");
            r = TSS2_FAPI_RC_MEMORY;
            goto error;
        }
        list_node = list_node->next;
    }
    free_string_list(list_node1);
    return TSS2_RC_SUCCESS;

error:
    if (*result)
        free_string_list(*result);
    if (list_node1)
        free_string_list(list_node1);
    return r;
}

/** Prepare the creation of a primary key.
 *
 * Depending on the parameters the creation of an endorsement or storage root key
 * will be prepared.
 *
 * @param[in] context The FAPI_CONTEXT.
 * @param[in] ktype The type of key TSS2_EK or TSS2_SRK.
 * @retval TSS2_RC_SUCCESS on success.
 * @retval TSS2_FAPI_RC_BAD_VALUE if a wrong type was passed.
 * @retval TSS2_ESYS_RC_* possible error codes of ESAPI.
 * @retval TSS2_FAPI_RC_MEMORY if not enough memory can be allocated.
 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
 * @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_FAPI_RC_IO_ERROR if an error occurred while accessing the
 *         object store.
 * @retval TSS2_FAPI_RC_GENERAL_FAILURE if an internal error occurred.
 * @retval TSS2_FAPI_RC_PATH_NOT_FOUND if a FAPI object path was not found
 *         during authorization.
 * @retval TSS2_FAPI_RC_KEY_NOT_FOUND if a key was not found.
 * @retval TSS2_FAPI_RC_NOT_PROVISIONED FAPI was not provisioned.
 * @retval TSS2_FAPI_RC_BAD_PATH if the path is used in inappropriate context
 *         or contains illegal characters.
 */
TSS2_RC
ifapi_init_primary_async(FAPI_CONTEXT *context, TSS2_KEY_TYPE ktype)
{
    TSS2_RC r;
    TPMS_POLICY *policy;

    r = TSS2_RC_SUCCESS;

    if (ktype == TSS2_EK) {
        /* Values set according to EK credential profile. */
        if (context->cmd.Provision.public_templ.public.publicArea.type == TPM2_ALG_RSA) {
            context->cmd.Provision.public_templ.public.publicArea.unique.rsa.size = 256;
        } else if (context->cmd.Provision.public_templ.public.publicArea.type == TPM2_ALG_ECC) {
            context->cmd.Provision.public_templ.public.publicArea.unique.ecc.x.size = 32;
            context->cmd.Provision.public_templ.public.publicArea.unique.ecc.y.size = 32;
        }
        policy = context->profiles.default_profile.ek_policy;
    } else if (ktype == TSS2_SRK) {
        policy = context->profiles.default_profile.srk_policy;
    } else {
        return_error(TSS2_FAPI_RC_BAD_VALUE,
                     "Invalid key type. Only EK or SRK allowed");
    }

    if (policy) {
        /* Duplicate policy to prevent profile policy from cleanup. */
        policy = ifapi_copy_policy(policy);
        return_if_null(policy, "Out of memory.", TSS2_FAPI_RC_MEMORY);

        r = ifapi_calculate_tree(context, NULL, /**< no path needed */
                                 policy,
                                 context->profiles.default_profile.nameAlg,
                                 &context->cmd.Provision.digest_idx,
                                 &context->cmd.Provision.hash_size);
        if (r) {
            LOG_ERROR("Policy calculation");
            SAFE_FREE(policy);
            return r;
        }

        context->cmd.Provision.public_templ.public.publicArea.authPolicy.size =
            context->cmd.Provision.hash_size;
        memcpy(&context->cmd.Provision.public_templ.public.publicArea.authPolicy.buffer[0],
               &policy->policyDigests.digests[context->policy.digest_idx].digest,
               context->cmd.Provision.hash_size);
    }
    context->createPrimary.pkey_object.policy = policy;
    context->createPrimary.pkey_object.objectType = IFAPI_KEY_OBJ;

    memset(&context->cmd.Provision.inSensitive, 0, sizeof(TPM2B_SENSITIVE_CREATE));
    memset(&context->cmd.Provision.outsideInfo, 0, sizeof(TPM2B_DATA));
    memset(&context->cmd.Provision.creationPCR, 0, sizeof(TPML_PCR_SELECTION));

    context->primary_state = PRIMARY_AUTHORIZE_HIERARCHY;
    return r;
}

/** Finalize the creation of a primary key.
 *
 * Depending on the parameters the creation of an endorsement key or a storage root key
 * will be finalized. The created object with the all information needed by FAPI will
 * be stored in the FAPI context.
 *
 * @param[in] context The FAPI_CONTEXT.
 * @param[in] ktype The type of key TSS2_EK or TSS2_SRK.
 * @param[in,out] hierarchy The hiearchy used for primary creation.
 *
 * @retval TSS2_RC_SUCCESS on success.
 * @retval TSS2_FAPI_RC_TRY_AGAIN if the execution cannot be completed.
 * @retval TSS2_FAPI_RC_BAD_VALUE if a wrong type was passed.
 * @retval TSS2_ESYS_RC_* possible error codes of ESAPI.
 * @retval TSS2_FAPI_RC_AUTHORIZATION_UNKNOWN if a required authorization callback
 *         is not set.
 * @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.
 * @retval TSS2_FAPI_RC_BAD_SEQUENCE if the context has an asynchronous
 *         operation already pending.
 * @retval TSS2_FAPI_RC_AUTHORIZATION_FAILED if the authorization attempt fails.
 * @retval TSS2_FAPI_RC_PATH_NOT_FOUND if a FAPI object path was not found
 *         during authorization.
 * @retval TSS2_FAPI_RC_KEY_NOT_FOUND if a key was not found.
 * @retval TSS2_FAPI_RC_IO_ERROR if an error occured while accessing the
 *         object store.
 * @retval TSS2_FAPI_RC_POLICY_UNKNOWN if policy search for a certain policy digest
 *         was not successful.
 */
TSS2_RC
ifapi_init_primary_finish(FAPI_CONTEXT *context, TSS2_KEY_TYPE ktype, IFAPI_OBJECT *hierarchy)
{
    TSS2_RC r;
    ESYS_TR primaryHandle;
    TPM2B_PUBLIC *outPublic = NULL;
    TPM2B_CREATION_DATA *creationData = NULL;
    TPM2B_DIGEST *creationHash = NULL;
    TPMT_TK_CREATION *creationTicket = NULL;
    IFAPI_KEY *pkey = &context->createPrimary.pkey_object.misc.key;
    NODE_STR_T *k_sub_path = NULL;
    ESYS_TR auth_session;

    switch (context->primary_state) {
    statecase(context->primary_state, PRIMARY_AUTHORIZE_HIERARCHY);
        if (hierarchy->misc.hierarchy.with_auth == TPM2_YES || policy_digest_size(hierarchy)) {
            r = ifapi_authorize_object(context, hierarchy, &auth_session);
            FAPI_SYNC(r, "Authorize hierarchy.", error_cleanup);
        } else {
            auth_session = context->session1;
        }
        r = Esys_CreatePrimary_Async(context->esys, hierarchy->handle,
                                     (auth_session == ESYS_TR_NONE) ?
                                     ESYS_TR_PASSWORD : auth_session,
                                     ESYS_TR_NONE, ESYS_TR_NONE,
                                     &context->cmd.Provision.inSensitive,
                                     &context->cmd.Provision.public_templ.public,
                                     &context->cmd.Provision.outsideInfo,
                                     &context->cmd.Provision.creationPCR);
        goto_if_error_reset_state(r, "CreatePrimary", error_cleanup);

        fallthrough;

    statecase(context->primary_state, PRIMARY_WAIT_FOR_PRIMARY);
        r = Esys_CreatePrimary_Finish(context->esys,
                                      &primaryHandle, &outPublic, &creationData, &creationHash,
                                      &creationTicket);
        if (base_rc(r) == TSS2_BASE_RC_TRY_AGAIN)
            return TSS2_FAPI_RC_TRY_AGAIN;

        /* Retry with authorization callback after trial with null auth */
        if (number_rc(r) == TPM2_RC_BAD_AUTH
            && hierarchy->misc.hierarchy.with_auth == TPM2_NO) {
            char *description;
            r = ifapi_get_description(hierarchy, &description);
            return_if_error(r, "Get description");

            r = ifapi_set_auth(context, hierarchy, description);
            SAFE_FREE(description);
            goto_if_error_reset_state(r, "CreatePrimary", error_cleanup);

            r = Esys_CreatePrimary_Async(context->esys, hierarchy->handle,
                                         (context->session1 == ESYS_TR_NONE) ?
                                         ESYS_TR_PASSWORD : context->session1,
                                         ESYS_TR_NONE, ESYS_TR_NONE,
                                         &context->cmd.Provision.inSensitive,
                                         &context->cmd.Provision.public_templ.public,
                                         &context->cmd.Provision.outsideInfo,
                                         &context->cmd.Provision.creationPCR);
            goto_if_error_reset_state(r, "CreatePrimary", error_cleanup);

            if (ktype == TSS2_EK) {
                context->state = PROVISION_AUTH_EK_AUTH_SENT;
            } else {
                context->state = PROVISION_AUTH_SRK_AUTH_SENT;
            }
            hierarchy->misc.hierarchy.with_auth = TPM2_YES;
            return TSS2_FAPI_RC_TRY_AGAIN;

        } else {
            goto_if_error_reset_state(r, "FAPI Provision", error_cleanup);
        }
        /* Set EK or SRK handle in context. */
        if (ktype == TSS2_EK) {
            context->ek_handle = primaryHandle;
        } else if (ktype == TSS2_SRK) {
            context->srk_handle = primaryHandle;
        } else {
            return_error(TSS2_FAPI_RC_BAD_VALUE,
                         "Invalid key type. Only EK or SRK allowed");
        }

        /* Prepare serialization of pkey to key store. */

        SAFE_FREE(pkey->serialization.buffer);
        r = Esys_TR_Serialize(context->esys, primaryHandle, &pkey->serialization.buffer,
                          &pkey->serialization.size);
        goto_if_error(r, "Error serialize esys object", error_cleanup);

        r = ifapi_get_name(&outPublic->publicArea, &pkey->name);
        goto_if_error(r, "Get primary name", error_cleanup);

        pkey->public = *outPublic;
        pkey->policyInstance = NULL;
        pkey->creationData = *creationData;
        pkey->creationTicket = *creationTicket;
        pkey->description = NULL;
        pkey->certificate = NULL;

        /* Cleanup unused information */
        SAFE_FREE(outPublic);
        SAFE_FREE(creationData);
        SAFE_FREE(creationHash);
        SAFE_FREE(creationTicket);

        if (pkey->public.publicArea.type == TPM2_ALG_RSA)
            pkey->signing_scheme = context->profiles.default_profile.rsa_signing_scheme;
        else
            pkey->signing_scheme = context->profiles.default_profile.ecc_signing_scheme;
        context->createPrimary.pkey_object.handle = primaryHandle;
        SAFE_FREE(pkey->serialization.buffer);
        return TSS2_RC_SUCCESS;

    statecasedefault(context->primary_state);
    }

error_cleanup:
    ifapi_cleanup_ifapi_object(&context->createPrimary.pkey_object);
    free_string_list(k_sub_path);
    SAFE_FREE(pkey->serialization.buffer);
    ifapi_cleanup_ifapi_object(&context->createPrimary.pkey_object);
    return r;
}

/** Prepare the loading of a primary key from key store.
 *
 * The asynchronous loading or the key from keystore will be prepared and
 * the path will be stored in the FAPI context.
 *
 * @param[in] context The FAPI_CONTEXT.
 * @param[in] path The FAPI path of the primary key.
 *
 * @retval TSS2_RC_SUCCESS on success.
 * @retval TSS2_FAPI_RC_BAD_VALUE if a wrong type was passed.
 * @retval TSS2_FAPI_RC_IO_ERROR if an I/O error was encountered.
 * @retval TSS2_FAPI_RC_PATH_NOT_FOUND if the file does not exist.
 * @retval TSS2_FAPI_RC_MEMORY if memory could not be allocated for path names.
 * @retval TSS2_FAPI_RC_KEY_NOT_FOUND if a key was not found.
 * @retval TSS2_FAPI_RC_NOT_PROVISIONED FAPI was not provisioned.
 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
 * @retval TSS2_FAPI_RC_BAD_PATH if the path is used in inappropriate context
 *         or contains illegal characters.
 */
TSS2_RC
ifapi_load_primary_async(FAPI_CONTEXT *context, char *path)
{

    TSS2_RC r;

    memset(&context->createPrimary.pkey_object, 0, sizeof(IFAPI_OBJECT));
    context->createPrimary.path = path;
    r = ifapi_keystore_load_async(&context->keystore, &context->io, path);
    return_if_error2(r, "Could not open: %s", path);
    context->primary_state = PRIMARY_READ_KEY;
    return TSS2_RC_SUCCESS;

}

/** State machine to finalize the loading of a primary key from key store.
 *
 * The asynchronous loading or the key from keystore will be finalized.
 * Afterwards the hierarchy object, which will be used for authorization will
 * be loaded and the ESAPI functions for primary generation will be called
 * if the primary is not persistent.
 *
 * @param[in] context The FAPI_CONTEXT.
 * @param[out] handle The object handle of the primary key.
 *
 * @retval TSS2_RC_SUCCESS on success.
 * @retval TSS2_FAPI_RC_BAD_VALUE if a wrong type was passed.
 * @retval TSS2_FAPI_RC_PATH_NOT_FOUND if the hierarchy file does not exist.
 * @retval TSS2_FAPI_RC_IO_ERROR if an I/O error was encountered.
 * @retval TSS2_FAPI_RC_MEMORY if memory could not be allocated for path names.
 * @retval TSS2_ESYS_RC_* possible error codes of ESAPI.
 * @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_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_KEY_NOT_FOUND if a key was not found.
 * @retval TSS2_FAPI_RC_AUTHORIZATION_UNKNOWN if a required authorization callback
 *         is not set.
 * @retval TSS2_FAPI_RC_AUTHORIZATION_FAILED if the authorization attempt fails.
 * @retval TSS2_FAPI_RC_POLICY_UNKNOWN if policy search for a certain policy digest
 *         was not successful.
 * @retval TSS2_FAPI_RC_NOT_PROVISIONED FAPI was not provisioned.
 * @retval TSS2_FAPI_RC_BAD_PATH if the path is used in inappropriate context
 *         or contains illegal characters.
 */
TSS2_RC
ifapi_load_primary_finish(FAPI_CONTEXT *context, ESYS_TR *handle)
{
    TSS2_RC r;
    IFAPI_OBJECT *hierarchy = &context->createPrimary.hierarchy;

    TPM2B_PUBLIC *outPublic = NULL;
    TPM2B_CREATION_DATA *creationData = NULL;
    TPM2B_DIGEST *creationHash = NULL;
    TPMT_TK_CREATION *creationTicket = NULL;
    IFAPI_OBJECT *pkey_object = &context->createPrimary.pkey_object;
    IFAPI_KEY *pkey = &context->createPrimary.pkey_object.misc.key;
    TPMS_CAPABILITY_DATA **capabilityData = &context->createPrimary.capabilityData;
    TPMI_YES_NO moreData;
    ESYS_TR auth_session = ESYS_TR_NONE; /* Initialized due to scanbuild */

    LOG_TRACE("call");

    switch (context->primary_state) {
    statecase(context->primary_state, PRIMARY_READ_KEY);
        /* Read the primary key from keystore. */
        r = ifapi_keystore_load_finish(&context->keystore, &context->io,
                                       pkey_object);
        return_try_again(r);
        return_if_error(r, "read_finish failed");

        r = ifapi_initialize_object(context->esys, pkey_object);
        goto_if_error_reset_state(r, "Initialize key object", error_cleanup);

        /* Check whether a persistent key was loaded.
           In this case the handle has already been set. */
        if (pkey_object->handle != ESYS_TR_NONE) {
            if (pkey->creationTicket.hierarchy == TPM2_RH_EK) {
                context->ek_persistent = true;
            } else {
                context->srk_persistent = true;
            }
            /* It has to be checked whether the persistent handle exists. */
            context->primary_state = PRIMARY_VERIFY_PERSISTENT;
            return TSS2_FAPI_RC_TRY_AGAIN;
        }
        else {
            if (pkey->creationTicket.hierarchy == TPM2_RH_EK) {
                context->ek_persistent = false;
            } else {
                context->srk_persistent = false;
            }
        }
        fallthrough;

    statecase(context->primary_state, PRIMARY_READ_HIERARCHY);
        /* The hierarchy object ussed for auth_session will be loaded from key store. */
        if (pkey->creationTicket.hierarchy == TPM2_RH_EK) {
            r = ifapi_keystore_load_async(&context->keystore, &context->io, "/HE");
            return_if_error2(r, "Could not open hierarchy /HE");
        } else if (pkey->creationTicket.hierarchy == TPM2_RH_NULL) {
            r = ifapi_keystore_load_async(&context->keystore, &context->io, "/HN");
            return_if_error2(r, "Could not open hierarchy /HN");
        } else {
            r = ifapi_keystore_load_async(&context->keystore, &context->io, "/HS");
            return_if_error2(r, "Could not open hierarchy /HS");
        }
        fallthrough;

    statecase(context->primary_state, PRIMARY_READ_HIERARCHY_FINISH);
        r = ifapi_keystore_load_finish(&context->keystore, &context->io, hierarchy);
        return_try_again(r);
        return_if_error(r, "read_finish failed");

        r = ifapi_initialize_object(context->esys, hierarchy);
        goto_if_error_reset_state(r, "Initialize hierarchy object", error_cleanup);

        if (pkey->creationTicket.hierarchy == TPM2_RH_EK) {
            hierarchy->handle = ESYS_TR_RH_ENDORSEMENT;
        } else if (pkey->creationTicket.hierarchy == TPM2_RH_NULL) {
            hierarchy->handle = ESYS_TR_RH_NULL;
        } else {
            hierarchy->handle = ESYS_TR_RH_OWNER;
        }
        fallthrough;

    statecase(context->primary_state, PRIMARY_AUTHORIZE_HIERARCHY);
        /* The asynchronous authorization of the hierarchy needed for primary. */
        r = ifapi_authorize_object(context, hierarchy, &auth_session);
        FAPI_SYNC(r, "Authorize hierarchy.", error_cleanup);

        memset(&context->createPrimary.inSensitive, 0, sizeof(TPM2B_SENSITIVE_CREATE));
        memset(&context->createPrimary.outsideInfo, 0, sizeof(TPM2B_DATA));
        memset(&context->createPrimary.creationPCR, 0, sizeof(TPML_PCR_SELECTION));
        fallthrough;

    statecase(context->primary_state, PRIMARY_GET_AUTH_VALUE);
        /* Get the auth value to be stored in inSensitive */
        r = ifapi_set_auth_primary(context, pkey_object,
                                   &context->createPrimary.inSensitive.sensitive);
        return_try_again(r);
        goto_if_error_reset_state(r, "Get auth value for primary", error_cleanup);

        /* Prepare primary creation. */
        TPM2B_PUBLIC public = pkey->public;
        memset(&public.publicArea.unique, 0, sizeof(TPMU_PUBLIC_ID));

        r = Esys_CreatePrimary_Async(context->esys, hierarchy->handle,
                                     auth_session, ESYS_TR_NONE, ESYS_TR_NONE,
                                     &context->createPrimary.inSensitive,
                                     &public,
                                     &context->createPrimary.outsideInfo,
                                     &context->createPrimary.creationPCR);
        return_if_error(r, "CreatePrimary");
        fallthrough;

    statecase(context->primary_state, PRIMARY_HAUTH_SENT);
        if (context->createPrimary.handle) {
            *handle = context->createPrimary.handle;
            context->primary_state = PRIMARY_CREATED;
            return TSS2_FAPI_RC_TRY_AGAIN;
        } else {
            r = Esys_CreatePrimary_Finish(context->esys,
                                          &pkey_object->handle, &outPublic,
                                          &creationData, &creationHash,
                                          &creationTicket);
            return_try_again(r);
            goto_if_error_reset_state(r, "FAPI regenerate primary", error_cleanup);
        }
        *handle = pkey_object->handle;
        context->primary_state = PRIMARY_INIT;
        break;

    statecase(context->primary_state, PRIMARY_VERIFY_PERSISTENT);
        /* Check the TPM capabilities for the persistent handle. */
        r = Esys_GetCapability_Async(context->esys,
                                     ESYS_TR_NONE, ESYS_TR_NONE, ESYS_TR_NONE,
                                     TPM2_CAP_HANDLES,
                                     pkey_object->misc.key.persistent_handle, 1);
        goto_if_error(r, "Esys_GetCapability_Async", error_cleanup);
        fallthrough;

    statecase(context->primary_state, PRIMARY_GET_CAP);
        r = Esys_GetCapability_Finish(context->esys, &moreData, capabilityData);
        return_try_again(r);
        goto_if_error_reset_state(r, "GetCapablity_Finish", error_cleanup);

        /* Check whether the persistent handle exists. */
        if ((*capabilityData)->data.handles.count != 0 &&
            (*capabilityData)->data.handles.handle[0] ==
            pkey_object->misc.key.persistent_handle) {
            /* Persistent handle found. */
            SAFE_FREE(*capabilityData);
            *handle = pkey_object->handle;
            break;
        }
        goto_error(r, TSS2_FAPI_RC_KEY_NOT_FOUND ,
                   "The persistent handle 0x%x does not exist. "
                   "The TPM state and the keystore state do not match."
,                   error_cleanup, pkey_object->misc.key.persistent_handle);
        fallthrough;

    statecasedefault(context->primary_state);
    }
    SAFE_FREE(outPublic);
    SAFE_FREE(creationData);
    SAFE_FREE(creationHash);
    SAFE_FREE(creationTicket);
    ifapi_cleanup_ifapi_object(&context->createPrimary.hierarchy);
    return TSS2_RC_SUCCESS;

error_cleanup:
    SAFE_FREE(*capabilityData);
    SAFE_FREE(outPublic);
    SAFE_FREE(creationData);
    SAFE_FREE(creationHash);
    SAFE_FREE(creationTicket);
    ifapi_cleanup_ifapi_object(&context->createPrimary.hierarchy);
    ifapi_cleanup_ifapi_object(&context->createPrimary.pkey_object);
    return r;
}

/** Prepare session for FAPI command execution.
 *
 * It will be checked whether the context of FAPI and ESAPI is initialized
 * and whether no other FAPI command session is running.
 * Also some handle variables in the context are initialized.
 *
 * @param[in] context The FAPI_CONTEXT.
 *
 * @retval TSS2_RC_SUCCESS on success.
 * @retval TSS2_FAPI_RC_BAD_REFERENCE if the context is not initialized.
 * @retval TSS2_FAPI_RC_BAD_SEQUENCE If a FAPI command session is active.
 * @retval TSS2_FAPI_RC_NO_TPM if the ESAPI context is not initialized.
 */
TSS2_RC
ifapi_session_init(FAPI_CONTEXT *context)
{
    LOG_TRACE("call");
    return_if_null(context, "No context", TSS2_FAPI_RC_BAD_REFERENCE);

    return_if_null(context->esys, "No context", TSS2_FAPI_RC_NO_TPM);

    if (context->state != _FAPI_STATE_INIT) {
        return_error(TSS2_FAPI_RC_BAD_SEQUENCE, "Invalid State");
    }

    context->session1 = ESYS_TR_NONE;
    context->session2 = ESYS_TR_NONE;
    context->policy.session = ESYS_TR_NONE;
    context->srk_handle = ESYS_TR_NONE;
    return TSS2_RC_SUCCESS;
}

/** Prepare session for FAPI command execution without TPM.
 *
 * It will be checked whether the context of FAPI is initialized
 * and whether no other FAPI command session is running.
 * Also some handle variables in the context are initialized.
 *
 * @param[in] context The FAPI_CONTEXT.
 *
 * @retval TSS2_RC_SUCCESS on success.
 * @retval TSS2_FAPI_RC_BAD_REFERENCE if the context is not initialized.
 * @retval TSS2_FAPI_RC_BAD_SEQUENCE If a FAPI command session is active.
 */
TSS2_RC
ifapi_non_tpm_mode_init(FAPI_CONTEXT *context)
{
    LOG_TRACE("call");
    return_if_null(context, "No context", TSS2_FAPI_RC_BAD_REFERENCE);

    if (context->state != _FAPI_STATE_INIT) {
        return_error(TSS2_FAPI_RC_BAD_SEQUENCE, "Invalid State");
    }

    context->session1 = ESYS_TR_NONE;
    context->session2 = ESYS_TR_NONE;
    context->policy.session = ESYS_TR_NONE;
    context->srk_handle = ESYS_TR_NONE;
    return TSS2_RC_SUCCESS;
}

/** Cleanup FAPI sessions in error cases.
 *
 * The uses sessions and the SRK (if not persistent) will be flushed
 * non asynchronous in error cases.
 *
 * @param[in,out] context The FAPI_CONTEXT.
 */
void
ifapi_session_clean(FAPI_CONTEXT *context)
{
    if (context->policy_session && context->policy_session != ESYS_TR_NONE) {
        Esys_FlushContext(context->esys, context->policy_session);
    }
    if (context->session1 != ESYS_TR_NONE) {
        if (Esys_FlushContext(context->esys, context->session1) != TSS2_RC_SUCCESS) {
            LOG_ERROR("Cleanup session failed.");
        }
        context->session1 = ESYS_TR_NONE;
    }
    if (context->session2 != ESYS_TR_NONE) {
        if (Esys_FlushContext(context->esys, context->session2) != TSS2_RC_SUCCESS) {
            LOG_ERROR("Cleanup session failed.");
            context->session2 = ESYS_TR_NONE;
        }
    }
    if (!context->srk_persistent && context->srk_handle != ESYS_TR_NONE) {
        if (Esys_FlushContext(context->esys, context->srk_handle) != TSS2_RC_SUCCESS) {
            LOG_ERROR("Cleanup Policy Session  failed.");
        }
        context->srk_handle = ESYS_TR_NONE;
    }
    context->srk_persistent = false;
}

/** State machine for asynchronous cleanup of a FAPI session.
 *
 * Used sessions and the SRK will be flushed.
 *
 * @param[in] context The FAPI_CONTEXT storing the used handles.
 *
 * @retval TSS2_RC_SUCCESS on success.
 * @retval TSS2_ESYS_RC_* possible error codes of ESAPI.
 * @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.
 */
TSS2_RC
ifapi_cleanup_session(FAPI_CONTEXT *context)
{
    TSS2_RC r;

    /* Policy sessions were closed after successful execution. */
    context->policy_session = ESYS_TR_NONE;

    switch (context->cleanup_state) {
        statecase(context->cleanup_state, CLEANUP_INIT);
            if (context->session1 != ESYS_TR_NONE) {
                r = Esys_FlushContext_Async(context->esys, context->session1);
                try_again_or_error(r, "Flush session.");
            }
            fallthrough;

        statecase(context->cleanup_state, CLEANUP_SESSION1);
            if (context->session1 != ESYS_TR_NONE) {
                r = Esys_FlushContext_Finish(context->esys);
                try_again_or_error(r, "Flush session.");
            }
            context->session1 = ESYS_TR_NONE;

            if (context->session2 != ESYS_TR_NONE) {
                r = Esys_FlushContext_Async(context->esys, context->session2);
                try_again_or_error(r, "Flush session.");
            }
            fallthrough;

        statecase(context->cleanup_state, CLEANUP_SESSION2);
            if (context->session2 != ESYS_TR_NONE) {
                r = Esys_FlushContext_Finish(context->esys);
                try_again_or_error(r, "Flush session.");
            }
            context->session2 = ESYS_TR_NONE;

            if (!context->srk_persistent && context->srk_handle != ESYS_TR_NONE) {
                r = Esys_FlushContext_Async(context->esys, context->srk_handle);
                try_again_or_error(r, "Flush SRK.");
            }
            fallthrough;

        statecase(context->cleanup_state, CLEANUP_SRK);
            if (!context->srk_persistent && context->srk_handle != ESYS_TR_NONE) {
                r = Esys_FlushContext_Finish(context->esys);
                try_again_or_error(r, "Flush SRK.");

                context->srk_handle = ESYS_TR_NONE;
                context->srk_persistent = false;
            }
            context->cleanup_state = CLEANUP_INIT;
            return TSS2_RC_SUCCESS;

        statecasedefault(context->state);
    }
}

/** Cleanup primary keys in error cases (non asynchronous).
 *
 * @param[in] context The FAPI_CONTEXT storing the used handles.
 *
 * @retval TSS2_RC_SUCCESS on success.
 * @retval TSS2_ESYS_RC_* possible error codes of ESAPI.
 */
void
ifapi_primary_clean(FAPI_CONTEXT *context)
{
    if (!context->srk_persistent && context->srk_handle != ESYS_TR_NONE) {
        if (Esys_FlushContext(context->esys, context->srk_handle) != TSS2_RC_SUCCESS) {
            LOG_ERROR("Cleanup session failed.");
        }
        context->srk_handle = ESYS_TR_NONE;
    }
    if (!context->ek_persistent && context->ek_handle != ESYS_TR_NONE) {
        if (Esys_FlushContext(context->esys, context->ek_handle) != TSS2_RC_SUCCESS) {
            LOG_ERROR("Cleanup EK failed.");
        }
        context->ek_handle = ESYS_TR_NONE;
    }
    context->srk_persistent = false;
}

/** Prepare the session creation of a FAPI command.
 *
 * The initial state of the state machine for session creation will be determined.
 * Depending of the session_flags creation of a primary for the encryption of
 * the session secret can be adjusted.
 * The session passed session attributes will be used for the ESAPI command
 * Esys_TRSess_SetAttributes.
 *
 * @param[in] context The FAPI_CONTEXT storing the used handles.
 * @param[in] session_flags The flags to adjust used session and encryption
 *            key. With IFAPI_SESSION1 and IFAPI_SESSION2 the session creation
 *            for sesion1 and session2 can be activated, IFAPI_SESSION_GENEK
 *            triggers the creation of the primary for session secret encryption.
 * @param[in] attribute_flags1 The attributes used for session1.
 * @param[in] attribute_flags2 The attributes used for session2.
 *
 * @retval TSS2_RC_SUCCESS on success.
 * @retval TSS2_FAPI_RC_PATH_NOT_FOUND if the hierarchy file or the primary key file
 *         does not exist.
 * @retval TSS2_FAPI_RC_MEMORY if memory could not be allocated for path names.
 *         of the primary.
 * @retval TSS2_FAPI_RC_KEY_NOT_FOUND if a key was not found.
 * @retval TSS2_FAPI_RC_BAD_VALUE if an invalid value was passed into
 *         the function.
 * @retval TSS2_FAPI_RC_IO_ERROR if an error occurred while accessing the
 *         object store.
 * @retval TSS2_FAPI_RC_NOT_PROVISIONED FAPI was not provisioned.
 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
 * @retval TSS2_FAPI_RC_BAD_PATH if the path is used in inappropriate context
 *         or contains illegal characters.
 */
TSS2_RC
ifapi_get_sessions_async(FAPI_CONTEXT *context,
                         IFAPI_SESSION_TYPE session_flags,
                         TPMA_SESSION attribute_flags1,
                         TPMA_SESSION attribute_flags2)
{
    TSS2_RC r;

    LOG_TRACE("call");
    context->session_flags = session_flags;
    context->session1_attribute_flags = attribute_flags1;
    context->session2_attribute_flags = attribute_flags2;
    char *file = NULL;

    if (!(session_flags & IFAPI_SESSION_GENEK)) {
        context->srk_handle = ESYS_TR_NONE;
        context->session_state = SESSION_CREATE_SESSION;
        return TSS2_RC_SUCCESS;
    }

    context->primary_state = PRIMARY_INIT;
    r = ifapi_asprintf(&file, "%s%s", context->config.profile_name,
                       IFAPI_SRK_KEY_PATH);
    goto_if_error(r, "Error ifapi_asprintf", error_cleanup);

    r = ifapi_load_primary_async(context, file);
    return_if_error_reset_state(r, "Load EK");
    free(file);

    context->session_state = SESSION_WAIT_FOR_PRIMARY;
    return TSS2_RC_SUCCESS;

error_cleanup:
    SAFE_FREE(file);
    return r;
}

/** State machine for the session creation of a FAPI command.
 *
 * The sessions needed for a FAPI command will be created. If needed also the
 * primary key for session encryption will be created.
 *
 * @param[in] context The FAPI_CONTEXT storing the used handles.
 * @param[in] profile The FAPI profile will be used to adjust session parameters.
 * @param[in] hash_alg The hash algorithm used for the session.
 *
 * @retval TSS2_RC_SUCCESS on success.
 * @retval TSS2_FAPI_RC_IO_ERROR if an I/O error was encountered.
 * @retval TSS2_FAPI_RC_MEMORY if memory could not be allocated for path names.
 * @retval TSS2_ESYS_RC_* possible error codes of ESAPI.
 * @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_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_BAD_VALUE if an invalid value was passed into
 *         the function.
 * @retval TSS2_FAPI_RC_PATH_NOT_FOUND if a FAPI object path was not found
 *         during authorization.
 * @retval TSS2_FAPI_RC_KEY_NOT_FOUND if a key was not found.
 * @retval TSS2_FAPI_RC_AUTHORIZATION_UNKNOWN if a required authorization callback
 *         is not set.
 * @retval TSS2_FAPI_RC_AUTHORIZATION_FAILED if the authorization attempt fails.
 * @retval TSS2_FAPI_RC_POLICY_UNKNOWN if policy search for a certain policy digest
 *         was not successful.
 * @retval TSS2_FAPI_RC_NOT_PROVISIONED FAPI was not provisioned.
 * @retval TSS2_FAPI_RC_BAD_PATH if the path is used in inappropriate context
 *         or contains illegal characters.
 */
TSS2_RC
ifapi_get_sessions_finish(
    FAPI_CONTEXT *context,
    const IFAPI_PROFILE *profile,
    TPMI_ALG_HASH hash_alg)
{
    TSS2_RC r;

    switch (context->session_state) {
    statecase(context->session_state, SESSION_WAIT_FOR_PRIMARY);
        LOG_TRACE("**STATE** SESSION_WAIT_FOR_PRIMARY");
        r = ifapi_load_primary_finish(context, &context->srk_handle);
        return_try_again(r);

        ifapi_cleanup_ifapi_object(&context->createPrimary.pkey_object);
        return_if_error(r, "Load primary.");
        fallthrough;

    statecase(context->session_state, SESSION_CREATE_SESSION);
        LOG_TRACE("**STATE** SESSION_CREATE_SESSION");
        if (!(context->session_flags & IFAPI_SESSION1)) {
            LOG_TRACE("finished");
            return TSS2_RC_SUCCESS;
        }

        /* Initializing the first session for the caller */

        r = ifapi_get_session_async(context->esys, context->srk_handle, profile,
                                    hash_alg);
        return_if_error_reset_state(r, "Create FAPI session async");
        fallthrough;

    statecase(context->session_state, SESSION_WAIT_FOR_SESSION1);
        LOG_TRACE("**STATE** SESSION_WAIT_FOR_SESSION1");
        r = ifapi_get_session_finish(context->esys, &context->session1,
                                     context->session1_attribute_flags);
        return_try_again(r);
        return_if_error_reset_state(r, "Create FAPI session finish");

        if (!(context->session_flags & IFAPI_SESSION2)) {
            LOG_TRACE("finished");
            return TSS2_RC_SUCCESS;
        }

        /* Initializing the second session for the caller */

        r = ifapi_get_session_async(context->esys, context->srk_handle, profile,
                                    profile->nameAlg);
        return_if_error_reset_state(r, "Create FAPI session async");
        fallthrough;

    statecase(context->session_state, SESSION_WAIT_FOR_SESSION2);
        LOG_TRACE("**STATE** SESSION_WAIT_FOR_SESSION2");
        r = ifapi_get_session_finish(context->esys, &context->session2,
                                     context->session2_attribute_flags);
        return_try_again(r);

        return_if_error_reset_state(r, "Create FAPI session finish");
        break;

    statecasedefault(context->session_state);
    }

    return TSS2_RC_SUCCESS;
}

/** Merge profile already stored in FAPI context into a NV object template.
 *
 * The defaults for NV creation which are stored in the FAPI default profile
 * will be merged in the passed templates default values.
 *
 * @param[in] context The FAPI_CONTEXT with the default profile.
 * @param[in] template The template with the default values for the NV object.
 *
 * @retval TSS2_RC_SUCCESS on success.
 */
TSS2_RC
ifapi_merge_profile_into_nv_template(
    FAPI_CONTEXT *context,
    IFAPI_NV_TEMPLATE *template)
{
    const TPMA_NV extend_mask = TPM2_NT_EXTEND << TPMA_NV_TPM2_NT_SHIFT;
    const TPMA_NV counter_mask = TPM2_NT_COUNTER << TPMA_NV_TPM2_NT_SHIFT;
    const TPMA_NV bitfield_mask = TPM2_NT_BITS << TPMA_NV_TPM2_NT_SHIFT;
    const IFAPI_PROFILE *profile = &context->profiles.default_profile;
    size_t hash_size;

    template->public.nameAlg = profile->nameAlg;
    if ((template->public.attributes & extend_mask) == extend_mask) {
        /* The size of the NV ram to be extended must be read from the
           profile */
        hash_size = ifapi_hash_get_digest_size(profile->nameAlg);
        template->public.dataSize = hash_size;
    } else if ((template->public.attributes & counter_mask) == counter_mask ||
               (template->public.attributes & bitfield_mask) == bitfield_mask) {
        /* For bit fields and counters only size 8 is possible */
        template->public.dataSize = 8;
    } else {
        /* For normal NV ram the passed size will be used. */
        template->public.dataSize = context->nv_cmd.numBytes;
    }

    return TSS2_RC_SUCCESS;
}

/** Merge profile already stored in FAPI context into a key template.
 *
 * The defaults for key creation which are stored in the FAPI default profile
 * will be merged in the passed templates default values.
 *
 * @param[in] profile The profile which will be used to adjust the template.
 * @param[in] template The template with the default values for the key object.
 *
 * @retval TSS2_RC_SUCCESS on success.
 */
TSS2_RC
ifapi_merge_profile_into_template(
    const IFAPI_PROFILE *profile,
    IFAPI_KEY_TEMPLATE *template)
{
    /* Merge profile parameters */
    template->public.publicArea.type = profile->type;
    template->public.publicArea.nameAlg = profile->nameAlg;
    if (profile->type == TPM2_ALG_RSA) {
        template->public.publicArea.parameters.rsaDetail.keyBits = profile->keyBits;
        template->public.publicArea.parameters.rsaDetail.exponent = profile->exponent;
    } else if (profile->type == TPM2_ALG_ECC) {
        template->public.publicArea.parameters.eccDetail.curveID = profile->curveID;
        template->public.publicArea.parameters.eccDetail.kdf.scheme = TPM2_ALG_NULL;
    }

    /* Set remaining parameters depending on key type */
    if (template->public.publicArea.objectAttributes & TPMA_OBJECT_RESTRICTED) {
        if (template->public.publicArea.objectAttributes & TPMA_OBJECT_DECRYPT) {
            template->public.publicArea.parameters.asymDetail.symmetric =
            profile->sym_parameters;
        } else {
            template->public.publicArea.parameters.asymDetail.symmetric.algorithm =
            TPM2_ALG_NULL;
        }
        if (profile->type == TPM2_ALG_RSA) {
            if (template->public.publicArea.objectAttributes & TPMA_OBJECT_SIGN_ENCRYPT) {
                template->public.publicArea.parameters.rsaDetail.scheme.scheme =
                profile->rsa_signing_scheme.scheme;
                memcpy(&template->public.publicArea.parameters.rsaDetail.scheme.details,
                       &profile->rsa_signing_scheme.details, sizeof(TPMU_ASYM_SCHEME));
            } else {
                template->public.publicArea.parameters.rsaDetail.scheme.scheme = TPM2_ALG_NULL;
            }
        } else if (profile->type == TPM2_ALG_ECC) {
            if (template->public.publicArea.objectAttributes & TPMA_OBJECT_SIGN_ENCRYPT) {
                template->public.publicArea.parameters.eccDetail.scheme.scheme =
                profile->ecc_signing_scheme.scheme;
                memcpy(&template->public.publicArea.parameters.eccDetail.scheme.details,
                       &profile->ecc_signing_scheme.details, sizeof(TPMU_ASYM_SCHEME));
            } else {
                template->public.publicArea.parameters.eccDetail.scheme.scheme = TPM2_ALG_NULL;
            }
        } else {
            template->public.publicArea.parameters.asymDetail.scheme.scheme = TPM2_ALG_NULL;
        }
    } else {
        /* Non restricted key */
        template->public.publicArea.parameters.asymDetail.symmetric.algorithm =
        TPM2_ALG_NULL;
        template->public.publicArea.parameters.asymDetail.scheme.scheme = TPM2_ALG_NULL;
    }
    return TSS2_RC_SUCCESS;
}

/** Convert absolute path to FAPI path which can be used as parameter for FAPI commands.
 *
 * Function converts the absolute path to a FAPI path.
 *
 * @param[in] keystore The used keystore.
 * @param[out] path FAPI key path.
 */
static void
full_path_to_fapi_path(IFAPI_KEYSTORE *keystore, char *path)
{
    unsigned int start_pos, end_pos, i;
    const unsigned int path_length = strlen(path);
    size_t keystore_length = strlen(keystore->userdir);
    char fapi_path_delim;

    start_pos = 0;

    /* Check key store part of the path */
    if (strncmp(&path[0], keystore->userdir, keystore_length) == 0) {
        start_pos = strlen(keystore->userdir);
    } else {
        keystore_length = strlen(keystore->systemdir);
        if (strncmp(&path[0], keystore->systemdir, keystore_length) == 0)
            start_pos = strlen(keystore->systemdir);
    }
    if (!start_pos)
        return;

    /* Shift FAPI path to the beginning. */
    end_pos = path_length - start_pos;
    memmove(&path[0], &path[start_pos], end_pos);
    size_t ip = 0;
    size_t lp = strlen(path);

    /* Special handling for // */
    while (ip < lp) {
        if (strncmp(&path[ip], "//", 2) == 0) {
            memmove(&path[ip], &path[ip + 1], lp - ip);
            lp -= 1;
        } else {
            ip += 1;
        }
    }

    /* Special handling for policy path were the name of the object file
       is part of the path. */
    if (ifapi_path_type_p(path, IFAPI_POLICY_PATH))
        fapi_path_delim = '.';
    else
        fapi_path_delim = IFAPI_FILE_DELIM_CHAR;

    for (i = end_pos - 1; i > 0; i--) {
        if (path[i] == fapi_path_delim) {
            path[i] = '\0';
            break;
        }
    }
}

/** Asynchronous preparation for loading a key and parent keys.
 *
 * The key loading is prepared. The pathname will be extended if possible and
 * a linked list with the directories will be created.
 *
 * @param[in,out] context The FAPI_CONTEXT.
 * @param[in]     keyPath the key path without the parent directories
 *                of the key store. (e.g. HE/EK, HS/SRK/mykey)
 *
 * @retval TSS2_RC_SUCCESS If the preparation is successful.
 * @retval TSS2_FAPI_RC_MEMORY if memory could not be allocated for path names.
 * @retval TSS2_FAPI_RC_BAD_VALUE if an invalid value was passed into
 *         the function.
 * @retval TSS2_FAPI_RC_BAD_PATH if the path is used in inappropriate context
 *         or contains illegal characters.
 * @retval TSS2_FAPI_RC_PATH_NOT_FOUND if a FAPI object path was not found
 *         during authorization.
 */
TSS2_RC
ifapi_load_keys_async(FAPI_CONTEXT *context, char const *keyPath)
{
    TSS2_RC r;
    NODE_STR_T *path_list;
    size_t path_length;
    char *fapi_key_path = NULL;

    LOG_TRACE("Load key: %s", keyPath);
    fapi_key_path = strdup(keyPath);
    check_oom(fapi_key_path);
    full_path_to_fapi_path(&context->keystore, fapi_key_path);
    r = get_explicit_key_path(&context->keystore, fapi_key_path, &path_list);
    SAFE_FREE(fapi_key_path);
    return_if_error(r, "Compute explicit path.");

    context->loadKey.path_list = path_list;
    path_length = ifapi_path_length(path_list);
    r = ifapi_load_key_async(context, path_length);
    goto_if_error(r, "Load key async.", error);

    return TSS2_RC_SUCCESS;

 error:
    free_string_list( context->loadKey.path_list);
    return r;
}

/** Asynchronous preparation for loading of the parent keys.
 *
 * The key loading is prepared. The pathname will be extended if possible and
 * a linked list with the directories will be created.
 *
 * @param[in,out] context The FAPI_CONTEXT.
 * @param[in]     keyPath the key path without the parent directories
 *                of the key store. (e.g. HE/EK, HS/SRK/mykey)
 *
 * @retval TSS2_RC_SUCCESS If the preparation is successful.
 * @retval TSS2_FAPI_RC_MEMORY if memory could not be allocated for path names.
 * @retval TSS2_FAPI_RC_BAD_VALUE if an invalid value was passed into
 *         the function.
 * @retval TSS2_FAPI_RC_BAD_PATH if the path is used in inappropriate context
 *         or contains illegal characters.
 * @retval TSS2_FAPI_RC_PATH_NOT_FOUND if a FAPI object path was not found
 *         during authorization.
 */
TSS2_RC
ifapi_load_parent_keys_async(FAPI_CONTEXT *context, char const *keyPath)
{
    TSS2_RC r;
    NODE_STR_T *path_list;
    size_t path_length;
    char *fapi_key_path = NULL;

    LOG_TRACE("Load key: %s", keyPath);
    fapi_key_path = strdup(keyPath);
    check_oom(fapi_key_path);
    full_path_to_fapi_path(&context->keystore, fapi_key_path);
    r = get_explicit_key_path(&context->keystore, fapi_key_path, &path_list);
    SAFE_FREE(fapi_key_path);
    goto_if_error(r, "Compute explicit path.", error);

    context->loadKey.path_list = path_list;
    path_length = ifapi_path_length(path_list);
    r = ifapi_load_key_async(context, path_length - 1);
    return_if_error(r, "Load key async.");

    return TSS2_RC_SUCCESS;

 error:
    free_string_list(context->loadKey.path_list);
    return r;
}

/** Asynchronous finish function for loading a key.
  *
 * @param[in,out] context The FAPI_CONTEXT.
 * @param[in]     flush_parent If false the parent of the key to be loaded
 *                will not be flushed.
 * @param[out]    handle The ESYS handle of the key.
 * @param[out]    key_object The object which will be used for the
 *                authorization of the loaded key.
 * @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_MEMORY if not enough memory can be allocated.
 * @retval TSS2_FAPI_RC_GENERAL_FAILURE if an internal error occurred.
 * @retval TSS2_FAPI_RC_BAD_VALUE if an invalid value was passed into
 *         the function.
 * @retval TSS2_FAPI_RC_BAD_SEQUENCE if the context has an asynchronous
 *         operation already pending.
 * @retval TSS2_FAPI_RC_PATH_NOT_FOUND if a FAPI object path was not found
 *         during authorization.
 * @retval TSS2_FAPI_RC_KEY_NOT_FOUND if a key was not found.
 * @retval TSS2_FAPI_RC_IO_ERROR if an error occurred while accessing the
 *         object store.
 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
 * @retval TSS2_FAPI_RC_AUTHORIZATION_UNKNOWN if a required authorization callback
 *         is not set.
 * @retval TSS2_FAPI_RC_AUTHORIZATION_FAILED if the authorization attempt fails.
 * @retval TSS2_FAPI_RC_POLICY_UNKNOWN if policy search for a certain policy digest
 *         was not successful.
 * @retval TSS2_ESYS_RC_* possible error codes of ESAPI.
 * @retval TSS2_FAPI_RC_BAD_PATH if the path is used in inappropriate context
 *         or contains illegal characters.
 * @retval TSS2_FAPI_RC_NOT_PROVISIONED FAPI was not provisioned.
 */
TSS2_RC
ifapi_load_keys_finish(
    FAPI_CONTEXT *context,
    bool flush_parent,
    ESYS_TR *handle,
    IFAPI_OBJECT **key_object)
{
    TSS2_RC r;

    r = ifapi_load_key_finish(context, flush_parent);
    if (r == TSS2_FAPI_RC_TRY_AGAIN)
        return r;

    goto_if_error(r, "Load keys", error);

    *handle = context->loadKey.auth_object.handle;
    /* The current authorization object is the last key loaded and
       will be used. */
    *key_object = &context->loadKey.auth_object;
    free_string_list(context->loadKey.path_list);
    return TSS2_RC_SUCCESS;

 error:
    free_string_list(context->loadKey.path_list);
    return r;

}

/** Initialize state machine for loading a key.
 *
 * @param[in,out] context for storing all state information.
 * @param[in] position the position of the key in path list stored in
 *            context->loadKey.path_list.
 *
 * @retval TSS2_RC_SUCCESS on success.
 * @retval TSS2_FAPI_RC_MEMORY if memory could not be allocated for path names.
 */
TSS2_RC
ifapi_load_key_async(FAPI_CONTEXT *context, size_t position)
{
    context->loadKey.state = LOAD_KEY_GET_PATH;
    context->loadKey.position = position;
    context->loadKey.key_list = NULL;
    context->loadKey.parent_handle = ESYS_TR_NONE;

    return TSS2_RC_SUCCESS;
}

/** State machine for loading a key.
 *
 * A stack with all sup keys will be created and decremented during
 * the loading auf all keys.
 * The object of the loaded key will be stored in:
 * context->loadKey.auth_object
 *
 * @param[in,out] context for storing all state information.
 * @param[in]     flush_parent If flush_parent is false parent is
                  only flushed if a new parent is available.
 *
 * @retval TSS2_RC_SUCCESS If the loading of the key was successful.
 * @retval TSS2_ESYS_RC_* possible error codes of ESAPI.
 * @retval TSS2_FAPI_RC_MEMORY if not enough memory can be allocated.
 * @retval TSS2_FAPI_RC_GENERAL_FAILURE If an internal error occurs, which is
 *         not covered by other return codes.
 * @retval TSS2_FAPI_RC_BAD_VALUE If wrong values are detected during execution.
 * @retval TSS2_FAPI_RC_IO_ERROR If an error occurs during access to the policy
 *         store.
 * @retval TSS2_FAPI_RC_PATH_NOT_FOUND If an object needed for loading or
 *         authentication was not found.
 * @retval TSS2_FAPI_RC_POLICY_UNKNOWN If policy search for a certain policy digest was
 *         not successful.
 * @retval TPM2_RC_BAD_AUTH If the authentication for an object needed for loading
 *         fails.
 * @retval TSS2_FAPI_RC_AUTHORIZATION_UNKNOWN if a needed authorization callback
 *         is not defined.
 * @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_FAPI_RC_KEY_NOT_FOUND if a key was not found.
 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
 * @retval TSS2_FAPI_RC_AUTHORIZATION_FAILED if the authorization attempt fails.
 * @retval TSS2_FAPI_RC_BAD_PATH if the path is used in inappropriate context
 *         or contains illegal characters.
 * @retval TSS2_FAPI_RC_NOT_PROVISIONED FAPI was not provisioned.
 */
TSS2_RC
ifapi_load_key_finish(FAPI_CONTEXT *context, bool flush_parent)
{
    TSS2_RC r;
    NODE_STR_T *path_list = context->loadKey.path_list;
    size_t *position = &context->loadKey.position;
    IFAPI_OBJECT *key_object = NULL;
    IFAPI_KEY *key = NULL;
    ESYS_TR auth_session;

    switch (context->loadKey.state) {
    statecase(context->loadKey.state, LOAD_KEY_GET_PATH);
        context->loadKey.key_path = NULL;
        /* Compute path name of key to be loaded. */
        r = ifapi_path_string_n(&context->loadKey.key_path, NULL, path_list, NULL,
                                *position);
        LOG_TRACE("Load path %s", context->loadKey.key_path);
        return_if_error(r, "Compute key path.");

        context->loadKey.key_object = ifapi_allocate_object(context);
        goto_if_null2(context->loadKey.key_object, "Allocating key", r,
                      TSS2_FAPI_RC_MEMORY, error_cleanup);

        goto_if_null2(context->loadKey.key_path, "Invalid path", r,
                      TSS2_FAPI_RC_GENERAL_FAILURE,
                      error_cleanup); /**< to avoid scan-build errors. */

        /* Prepare key loading. */
        r = ifapi_keystore_load_async(&context->keystore, &context->io,
                                      context->loadKey.key_path);
        return_if_error2(r, "Could not open: %s", context->loadKey.key_path);
        fallthrough;

    statecase(context->loadKey.state, LOAD_KEY_READ_KEY);
        goto_if_null2(context->loadKey.key_path, "Invalid path", r,
                      TSS2_FAPI_RC_GENERAL_FAILURE,
                      error_cleanup); /**< to avoid scan-build errors. */

        key = &context->loadKey.key_object->misc.key;

        r = ifapi_keystore_load_finish(&context->keystore, &context->io,
                                       context->loadKey.key_object);
        if (r != TSS2_RC_SUCCESS) {
            ifapi_cleanup_ifapi_object(context->loadKey.key_object);
        }
        return_try_again(r);
        return_if_error(r, "read_finish failed");

        if (context->loadKey.key_object->objectType != IFAPI_KEY_OBJ)
            goto_error(r, TSS2_FAPI_RC_BAD_PATH, "%s is no key", error_cleanup,
                       context->loadKey.key_path);

        r = ifapi_initialize_object(context->esys, context->loadKey.key_object);
        goto_if_error_reset_state(r, "Initialize key object", error_cleanup);

        SAFE_FREE(context->loadKey.key_path);
        context->loadKey.handle = context->loadKey.key_object->handle;
        if (context->loadKey.handle != ESYS_TR_NONE) {
            /* Persistent key could be desearialized keys can be loaded */
            r = ifapi_copy_ifapi_key_object(&context->loadKey.auth_object,
                context->loadKey.key_object);
            goto_if_error(r, "Could not copy key object", error_cleanup);
            ifapi_cleanup_ifapi_object(context->loadKey.key_object);
            context->loadKey.state = LOAD_KEY_LOAD_KEY;

            return TSS2_FAPI_RC_TRY_AGAIN;
        }

        if (key->private.size == 0) {
            /* Create a deep copy of the primary key */
            r = ifapi_copy_ifapi_key_object(&context->createPrimary.pkey_object,
                                            context->loadKey.key_object);
            goto_if_error(r, "Could not copy primary key", error_cleanup);

            ifapi_cleanup_ifapi_key(key);
            context->primary_state = PRIMARY_READ_HIERARCHY;
            context->loadKey.state = LOAD_KEY_WAIT_FOR_PRIMARY;
            return TSS2_FAPI_RC_TRY_AGAIN;
        }
        IFAPI_OBJECT * copyToPush = malloc(sizeof(IFAPI_OBJECT));
        goto_if_null(copyToPush, "Out of memory", TSS2_FAPI_RC_MEMORY, error_cleanup);
        r = ifapi_copy_ifapi_key_object(copyToPush, context->loadKey.key_object);
        if (r) {
            free(copyToPush);
            LOG_ERROR("Could not create a copy to push");
            goto error_cleanup;
        }
        /* Add object to the list of keys to be loaded. */
        r = push_object_to_list(copyToPush, &context->loadKey.key_list);
        if (r) {
            free(copyToPush);
            LOG_ERROR("Out of memory");
            goto error_cleanup;
        }

        ifapi_cleanup_ifapi_object(context->loadKey.key_object);

        *position -= 1;
        context->loadKey.state = LOAD_KEY_GET_PATH;
        return TSS2_FAPI_RC_TRY_AGAIN;

    statecase(context->loadKey.state, LOAD_KEY_LOAD_KEY);
        if (!(context->loadKey.key_list)) {
            LOG_TRACE("All keys loaded.");
            return TSS2_RC_SUCCESS;
        }

        /* if flush_parent is false parent is only flushed if a new parent
           is available */
        if (!flush_parent && context->loadKey.parent_handle != ESYS_TR_NONE) {
            r = Esys_FlushContext(context->esys, context->loadKey.parent_handle);
            goto_if_error_reset_state(r, "Flush object", error_cleanup);
        }
        fallthrough;

    statecase(context->loadKey.state, LOAD_KEY_AUTHORIZE);
        key_object = context->loadKey.key_list->object;
        key = &key_object->misc.key;
        r = ifapi_authorize_object(context, &context->loadKey.auth_object, &auth_session);
        FAPI_SYNC(r, "Authorize key.", error_cleanup);

        /* Store parent handle in context for usage in ChangeAuth if not persistent */
        context->loadKey.parent_handle = context->loadKey.handle;
        if (context->loadKey.auth_object.misc.key.persistent_handle)
            context->loadKey.parent_handle_persistent = true;
        else
            context->loadKey.parent_handle_persistent = false;

        TPM2B_PRIVATE private;

        private.size = key->private.size;
        memcpy(&private.buffer[0], key->private.buffer, key->private.size);

        r = Esys_Load_Async(context->esys, context->loadKey.handle,
                            auth_session,
                            ESYS_TR_NONE, ESYS_TR_NONE,
                            &private, &key->public);
        goto_if_error(r, "Load async", error_cleanup);
        fallthrough;

    statecase(context->loadKey.state, LOAD_KEY_AUTH);
        r = Esys_Load_Finish(context->esys, &context->loadKey.handle);
        return_try_again(r);
        goto_if_error_reset_state(r, "Load", error_cleanup);

        /* The current parent is flushed if not prohibited by flush parent */
        if (flush_parent && context->loadKey.auth_object.objectType == IFAPI_KEY_OBJ &&
            ! context->loadKey.auth_object.misc.key.persistent_handle) {
            r = Esys_FlushContext(context->esys, context->loadKey.auth_object.handle);
            goto_if_error_reset_state(r, "Flush object", error_cleanup);

        }
        LOG_TRACE("New key used as auth object.");
        ifapi_cleanup_ifapi_object(&context->loadKey.auth_object);
        r = ifapi_copy_ifapi_key_object(&context->loadKey.auth_object,
                context->loadKey.key_list->object);
        goto_if_error(r, "Could not copy loaded key", error_cleanup);
        context->loadKey.auth_object.handle = context->loadKey.handle;
        IFAPI_OBJECT *top_obj = context->loadKey.key_list->object;
        ifapi_cleanup_ifapi_object(top_obj);
        SAFE_FREE(context->loadKey.key_list->object);
        r = pop_object_from_list(context, &context->loadKey.key_list);
        goto_if_error_reset_state(r, "Pop key failed.", error_cleanup);

        if (context->loadKey.key_list) {
            /* Object can be cleaned if it's not the last */
            ifapi_free_object(context, &top_obj);
        }

        context->loadKey.state = LOAD_KEY_LOAD_KEY;
        return TSS2_FAPI_RC_TRY_AGAIN;

    statecase(context->loadKey.state, LOAD_KEY_WAIT_FOR_PRIMARY);
        r = ifapi_load_primary_finish(context, &context->loadKey.handle);
        return_try_again(r);
        goto_if_error(r, "CreatePrimary", error_cleanup);

        /* Save the primary object for authorization */
        r = ifapi_copy_ifapi_key_object(&context->loadKey.auth_object,
                &context->createPrimary.pkey_object);
        goto_if_error(r, "Could not copy primary key", error_cleanup);

        if (context->loadKey.key_list) {
            context->loadKey.state = LOAD_KEY_LOAD_KEY;
            return TSS2_FAPI_RC_TRY_AGAIN;
        } else {
            LOG_TRACE("success");
            ifapi_cleanup_ifapi_object(context->loadKey.key_object);
            return TSS2_RC_SUCCESS;
        }
        break;

    statecasedefault(context->loadKey.state);
    }

error_cleanup:
    if (context->loadKey.handle && context->loadKey.handle != ESYS_TR_NONE &&
        context->loadKey.key_object->misc.key.persistent_handle) {
        Esys_FlushContext(context->esys, context->loadKey.handle);
    }
    ifapi_free_object_list(context->loadKey.key_list);
    ifapi_cleanup_ifapi_object(context->loadKey.key_object);
    SAFE_FREE(context->loadKey.key_path);
    return r;
}

/** Get the name alg corresponding to a FAPI object.
 *
 * @param[in] context The context with the default profile.
 * @param[in] object The object to be checked.
 * @retval TPMI_ALG_HASH The hash algorithm.
 * @retval 0 If no name alg can be assigned to the object.
 */
static size_t
get_name_alg(FAPI_CONTEXT *context, IFAPI_OBJECT *object)
{
    switch (object->objectType) {
    case IFAPI_KEY_OBJ:
        return object->misc.key.public.publicArea.nameAlg;
    case IFAPI_NV_OBJ:
        return object->misc.nv.public.nvPublic.nameAlg;
    case IFAPI_HIERARCHY_OBJ:
        return context->profiles.default_profile.nameAlg;
    default:
        return 0;
    }
}

/** Check whether policy session has to be flushed.
 *
 * Policy sessions with cleared continue session flag are not flushed in error
 * cases. Therefore the return code will be checked and if a policy session was
 * used the session will be flushed if the command was not executed successfully.
 *
 * @param[in,out] context for storing all state information.
 * @param[in] session the session to be checked whether flush is needed.
 * @param[in] r The return code of the command using the session.
 */
void
ifapi_flush_policy_session(FAPI_CONTEXT *context, ESYS_TR session, TSS2_RC r)
{
    if (session != context->session1) {
        /* A policy session was used instead auf the default session. */
        if (r != TSS2_RC_SUCCESS) {
            Esys_FlushContext(context->esys, session);
        }
    }
}

/** State machine to authorize a key, a NV object of a hierarchy.
 *
 * @param[in,out] context for storing all state information.
 * @param[in] object The FAPI object.
 * @param[out] session The session which can be used for object authorization.
 *
 * @retval TSS2_RC_SUCCESS If the authorization is successful
 * @retval TSS2_FAPI_RC_MEMORY if not enough memory can be allocated.
 * @retval TSS2_FAPI_RC_BAD_VALUE If wrong values are detected during execution.
 * @retval TSS2_FAPI_RC_IO_ERROR If an error occurs during access to the policy
 *         store.
 * @retval TSS2_FAPI_RC_PATH_NOT_FOUND If a policy for a certain path was not found.
 * @retval TSS2_FAPI_RC_POLICY_UNKNOWN If policy search for a certain policy digest was
 *         not successful.
 * @retval TPM2_RC_BAD_AUTH If the authentication for an object needed for the policy
 *         execution fails.
 * @retval TSS2_FAPI_RC_AUTHORIZATION_UNKNOWN if a needed authorization callback
           is not defined.
 * @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_AUTHORIZATION_FAILED if the authorization attempt fails.
 * @retval TSS2_FAPI_RC_GENERAL_FAILURE if an internal error occurred.
 * @retval TSS2_ESYS_RC_* possible error codes of ESAPI.
 * @retval TSS2_FAPI_RC_KEY_NOT_FOUND if a key was not found.
 */
TSS2_RC
ifapi_authorize_object(FAPI_CONTEXT *context, IFAPI_OBJECT *object, ESYS_TR *session)
{
    TSS2_RC r;
    TPMI_YES_NO auth_required;

    LOG_DEBUG("Authorize object: %x", object->handle);
    switch (object->authorization_state) {
        statecase(object->authorization_state, AUTH_INIT)
            LOG_TRACE("**STATE** AUTH_INIT");

            if (!policy_digest_size(object)) {
                /* No policy used authorization callbacks have to be called if necessary. */
                if (object_with_auth(object)) {
                    /* Check whether hierarchy was already authorized. */
                    if (object->objectType != IFAPI_HIERARCHY_OBJ ||
                        !object->misc.hierarchy.authorized) {
                        char *description = NULL;
                        r = ifapi_get_description(object, &description);
                        return_if_error(r, "Get description");

                        r = ifapi_set_auth(context, object, description);
                        SAFE_FREE(description);
                        return_if_error(r, "Set auth value");
                    }
                }
                /* No policy session needed current fapi session can be used */
                if (context->session1 && context->session1 != ESYS_TR_NONE)
                    *session = context->session1;
                else
                    /* Use password session if session1 had not been created */
                    *session = ESYS_TR_PASSWORD;
                break;
            }
            /* Save current object to be authorized in context. */
            context->current_auth_object = object;
            r = ifapi_policyutil_execute_prepare(context, get_name_alg(context, object),
                                                 object->policy);
            return_if_error(r, "Prepare policy execution.");

            /* Next state will switch from prev context to next context. */
            context->policy.util_current_policy = context->policy.util_current_policy->prev;
            object->authorization_state = AUTH_EXEC_POLICY;
            fallthrough;

        statecase(object->authorization_state, AUTH_EXEC_POLICY)
            *session = ESYS_TR_NONE;
            r = ifapi_policyutil_execute(context, session);
            if (r == TSS2_FAPI_RC_TRY_AGAIN)
                return r;

            return_if_error(r, "Execute policy.");

            r = Esys_TRSess_GetAuthRequired(context->esys, *session,
                                            &auth_required);
            return_if_error(r, "GetAuthRequired");

            /* Check whether PolicyCommand requiring authorization was executed */
            if (auth_required == TPM2_YES) {
                char* description;
                r = ifapi_get_description(object, &description);
                return_if_error(r, "Get description");
                r = ifapi_set_auth(context, object, description);
                SAFE_FREE(description);
                goto_if_error(r, "Set auth value", error);
            }
            /* Clear continue session flag, so policy session will be flushed after authorization */
            r = Esys_TRSess_SetAttributes(context->esys, *session, 0, TPMA_SESSION_CONTINUESESSION);
            goto_if_error(r, "Esys_TRSess_SetAttributes", error);
            break;

        general_failure(object->authorization_state)
    }

    object->authorization_state = AUTH_INIT;
    return TSS2_RC_SUCCESS;

error:
    /* No policy call was executed session can be flushed */
    Esys_FlushContext(context->esys, *session);
    return r;
}

/** State machine to write data to the NV ram of the TPM.
 *
 * The NV object will be read from object store and the data will be
 * written by one, or more than one if necessary, ESAPI calls to the NV ram of
 * the TPM.
 * The sub context nv_cmd will be prepared:
 * - data The buffer for the data which has to be written
 * - offset The current offset for writing
 * - numBytes The number of bytes which have to be written.
 *
 * @param[in,out] context for storing all state information.
 * @param[in] nvPath The fapi path of the NV object.
 * @param[in] param_offset The offset in the NV memory (will be stored in context).
 * @param[in] data The pointer to the data to be written.
 * @param[in] size The number of bytes to be written.
 *
 * @retval TSS2_RC_SUCCESS If data can be written.
 * @retval TSS2_ESYS_RC_* possible error codes of ESAPI.
 * @retval TSS2_FAPI_RC_MEMORY if not enough memory can be allocated.
 * @retval TSS2_FAPI_RC_BAD_VALUE If wrong values are detected during execution.
 * @retval TSS2_FAPI_RC_GENERAL_FAILURE If an internal error occurs, which is
 +         not covered by other return codes.
 * @retval TSS2_FAPI_RC_IO_ERROR If an error occurs during access to the object
 *         store.
 * @retval TSS2_FAPI_RC_PATH_NOT_FOUND The nv object or an object needed for
 *         authentication was not found.
 * @retval TSS2_FAPI_RC_POLICY_UNKNOWN If policy search for a certain policy digest was
 *          not successful.
 * @retval TPM2_RC_BAD_AUTH If the authentication for an object needed for the
 *         command execution fails.
 * @retval TSS2_FAPI_RC_AUTHORIZATION_UNKNOWN if a needed authorization callback
 *         is not defined.
 * @retval TSS2_FAPI_RC_BAD_PATH if a path is used in inappropriate context
 *         or contains illegal characters.
 * @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_FAPI_RC_KEY_NOT_FOUND if a key was not found.
 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
 * @retval TSS2_FAPI_RC_AUTHORIZATION_FAILED if the authorization attempt fails.
 * @retval TSS2_FAPI_RC_NOT_PROVISIONED FAPI was not provisioned.
 */
TSS2_RC
ifapi_nv_write(
    FAPI_CONTEXT *context,
    char         *nvPath,
    size_t         param_offset,
    uint8_t const *data,
    size_t         size)
{
    TSS2_RC r = TSS2_RC_SUCCESS;
    ESYS_TR auth_index;
    ESYS_TR nv_index = context->nv_cmd.esys_handle;
    IFAPI_OBJECT *object = &context->nv_cmd.nv_object;
    IFAPI_OBJECT *auth_object = &context->nv_cmd.auth_object;
    TPM2B_MAX_NV_BUFFER *aux_data = (TPM2B_MAX_NV_BUFFER *)&context->aux_data;
    char *nv_file_name = NULL;
    ESYS_TR auth_session;

    switch (context->nv_cmd.nv_write_state) {
    statecase(context->nv_cmd.nv_write_state, NV2_WRITE_INIT);
        memset(&context->nv_cmd.nv_object, 0, sizeof(IFAPI_OBJECT));
        context->nv_cmd.nvPath = nvPath;
        context->nv_cmd.offset = param_offset;
        context->nv_cmd.numBytes = size;
        context->nv_cmd.data = data;
        if (context->nv_cmd.numBytes > context->nv_buffer_max)
            aux_data->size = context->nv_buffer_max;
        else
            aux_data->size = context->nv_cmd.numBytes;
        context->nv_cmd.data_idx = 0;

        /* Use calloc to ensure zero padding for write buffer. */
        context->nv_cmd.write_data = calloc(size, 1);
        goto_if_null2(context->nv_cmd.write_data, "Out of memory.", r,
                      TSS2_FAPI_RC_MEMORY,
                      error_cleanup);
        memcpy(context->nv_cmd.write_data, data, size);
        memcpy(&aux_data->buffer[0], &context->nv_cmd.data[0], aux_data->size);

        /* Prepare reading of the key from keystore. */
        r = ifapi_keystore_load_async(&context->keystore, &context->io,
                                      context->nv_cmd.nvPath);
        return_if_error2(r, "Could not open: %s", context->nv_cmd.nvPath);
        fallthrough;

    statecase(context->nv_cmd.nv_write_state, NV2_WRITE_READ);
        r = ifapi_keystore_load_finish(&context->keystore, &context->io, object);
        return_try_again(r);
        return_if_error(r, "read_finish failed");

        if (object->objectType != IFAPI_NV_OBJ)
            goto_error(r, TSS2_FAPI_RC_BAD_PATH, "%s is no NV object.", error_cleanup,
                       context->nv_cmd.nvPath);

        r = ifapi_initialize_object(context->esys, object);
        goto_if_error_reset_state(r, "Initialize NV object", error_cleanup);

        /* Store object info in context */
        nv_index = context->nv_cmd.nv_object.handle;
        context->nv_cmd.esys_handle = nv_index;
        context->nv_cmd.nv_obj = object->misc.nv;

        /* Determine the object which will be uses for authorization. */
        if (object->misc.nv.public.nvPublic.attributes & TPMA_NV_PPWRITE) {
            ifapi_init_hierarchy_object(auth_object, ESYS_TR_RH_PLATFORM);
            auth_index = ESYS_TR_RH_PLATFORM;
        } else {
            if (object->misc.nv.public.nvPublic.attributes & TPMA_NV_OWNERWRITE) {
                ifapi_init_hierarchy_object(auth_object, ESYS_TR_RH_OWNER);
                auth_index = ESYS_TR_RH_OWNER;
            } else {
                auth_index = nv_index;
            }
            *auth_object = *object;
        }
        context->nv_cmd.auth_index = auth_index;

        /* Get A session for authorizing the NV write operation. */
        r = ifapi_get_sessions_async(context, IFAPI_SESSION_GENEK | IFAPI_SESSION1,
                                         TPMA_SESSION_DECRYPT, 0);
        goto_if_error(r, "Create sessions", error_cleanup);

        fallthrough;

    statecase(context->nv_cmd.nv_write_state, NV2_WRITE_WAIT_FOR_SESSSION);
        r = ifapi_get_sessions_finish(context, &context->profiles.default_profile,
                                      object->misc.nv.public.nvPublic.nameAlg);
        return_try_again(r);
        goto_if_error_reset_state(r, " FAPI create session", error_cleanup);

        fallthrough;

    statecase(context->nv_cmd.nv_write_state, NV2_WRITE_AUTHORIZE);
        r = ifapi_authorize_object(context, auth_object, &auth_session);
        FAPI_SYNC(r, "Authorize NV object.", error_cleanup);

        /* Prepare the writing to NV ram. */
        r = Esys_NV_Write_Async(context->esys,
                                context->nv_cmd.auth_index,
                                nv_index,
                                auth_session,
                                context->session2,
                                ESYS_TR_NONE,
                                aux_data,
                                context->nv_cmd.data_idx);
        goto_if_error_reset_state(r, " Fapi_NvWrite_Async", error_cleanup);

        if (!(object->misc.nv.public.nvPublic.attributes & TPMA_NV_NO_DA))
            context->nv_cmd.nv_write_state = NV2_WRITE_AUTH_SENT;
        else
            context->nv_cmd.nv_write_state = NV2_WRITE_NULL_AUTH_SENT;

        context->nv_cmd.bytesRequested = aux_data->size;

        fallthrough;

    case NV2_WRITE_AUTH_SENT:
    case NV2_WRITE_NULL_AUTH_SENT:
        r = Esys_NV_Write_Finish(context->esys);
        return_try_again(r);

        if (number_rc(r) == TPM2_RC_BAD_AUTH) {
            if (context->nv_cmd.nv_write_state == NV2_WRITE_NULL_AUTH_SENT) {
                IFAPI_OBJECT *auth_object = &context->nv_cmd.auth_object;
                char *description;
                r = ifapi_get_description(auth_object, &description);
                return_if_error(r, "Get description");
                r = ifapi_set_auth(context, auth_object, description);
                SAFE_FREE(description);
                goto_if_error_reset_state(r, " Fapi_NvWrite_Finish", error_cleanup);

                /* Prepare the writing to NV ram. */
                r = Esys_NV_Write_Async(context->esys,
                                        context->nv_cmd.auth_index,
                                        nv_index,
                                        (!context->policy.session
                                         || context->policy.session == ESYS_TR_NONE) ? context->session1 :
                                        context->policy.session,
                                        context->session2,
                                        ESYS_TR_NONE,
                                        aux_data,
                                        context->nv_cmd.data_idx);
                goto_if_error_reset_state(r, "FAPI NV_Write_Async", error_cleanup);

                context->nv_cmd.nv_write_state = NV2_WRITE_AUTH_SENT;
                return TSS2_FAPI_RC_TRY_AGAIN;
            }
        }
        goto_if_error_reset_state(r, "FAPI NV_Write_Finish", error_cleanup);

        context->nv_cmd.numBytes -= context->nv_cmd.bytesRequested;

        if (context->nv_cmd.numBytes > 0) {
            /* Increment data idx with number of transmitted bytes. */
            context->nv_cmd.data_idx += aux_data->size;
            if (context->nv_cmd.numBytes > context->nv_buffer_max)
                aux_data->size = context->nv_buffer_max;
            else
                aux_data->size = context->nv_cmd.numBytes;
            memcpy(&aux_data->buffer[0],
                   &context->nv_cmd.write_data[context->nv_cmd.data_idx],
                   aux_data->size);

            statecase(context->nv_cmd.nv_write_state, NV2_WRITE_AUTHORIZE2);
                r = ifapi_authorize_object(context, auth_object, &auth_session);
                FAPI_SYNC(r, "Authorize NV object.", error_cleanup);

            /* Prepare the writing to NV ram */
            r = Esys_NV_Write_Async(context->esys,
                                    context->nv_cmd.auth_index,
                                    nv_index,
                                    auth_session,
                                    context->session2,
                                    ESYS_TR_NONE,
                                    aux_data,
                                    context->nv_cmd.data_idx);
            goto_if_error_reset_state(r, "FAPI NV_Write", error_cleanup);

            context->nv_cmd.bytesRequested = aux_data->size;
            context->nv_cmd.nv_write_state = NV2_WRITE_AUTH_SENT;
            return TSS2_FAPI_RC_TRY_AGAIN;

        }
        fallthrough;

    statecase(context->nv_cmd.nv_write_state, NV2_WRITE_WRITE_PREPARE);
        /* Set written bit in keystore */
        context->nv_cmd.nv_object.misc.nv.public.nvPublic.attributes |= TPMA_NV_WRITTEN;
        /* Perform esys serialization if necessary */
        r = ifapi_esys_serialize_object(context->esys, &context->nv_cmd.nv_object);
        goto_if_error(r, "Prepare serialization", error_cleanup);

        /* Start writing the NV object to the key store */
        r = ifapi_keystore_store_async(&context->keystore, &context->io,
                                       context->nv_cmd.nvPath,
                                       &context->nv_cmd.nv_object);
        goto_if_error_reset_state(r, "Could not open: %s", error_cleanup,
                                  context->nv_cmd.nvPath);
        context->nv_cmd.nv_write_state = NV2_WRITE_WRITE;
        fallthrough;

    statecase(context->nv_cmd.nv_write_state, NV2_WRITE_WRITE);
        /* Finish writing the NV object to the key store */
        r = ifapi_keystore_store_finish(&context->keystore, &context->io);
        return_try_again(r);
        return_if_error_reset_state(r, "write_finish failed");

        LOG_DEBUG("success");
        r = TSS2_RC_SUCCESS;

        context->nv_cmd.nv_write_state = NV2_WRITE_INIT;
        break;

    statecasedefault(context->nv_cmd.nv_write_state);
    }

error_cleanup:
    SAFE_FREE(nv_file_name);
    SAFE_FREE(context->nv_cmd.write_data);
    return r;
}

/** State machine to read data from the NV ram of the TPM.
 *
 * Context nv_cmd has to be prepared before the call of this function:
 * - auth_index The ESAPI handle of the authorization object.
 * - numBytes The number of bytes which should be read.
 * - esys_handle The ESAPI handle of the NV object.
 *
 * @param[in,out] context for storing all state information.
 * @param[out] data the data fetched from TPM.
 * @param[in,out] size The number of bytes requested and fetched.
 *
 * @retval TSS2_RC_SUCCESS If the data was read successfully.
 * @retval TSS2_ESYS_RC_* possible error codes of ESAPI.
 * @retval TSS2_FAPI_RC_MEMORY if not enough memory can be allocated.
 * @retval TSS2_FAPI_RC_BAD_VALUE If wrong values are detected during execution.
 * @retval TSS2_FAPI_RC_GENERAL_FAILURE If an internal error occurs, which is
 +         not covered by other return codes.
 * @retval TSS2_FAPI_RC_IO_ERROR If an error occurs during access to the object
 *         store.
 * @retval TSS2_FAPI_RC_PATH_NOT_FOUND If a policy for a certain path was not found.
 * @retval TSS2_FAPI_RC_POLICY_UNKNOWN If policy search for a certain policy digest was
 *         not successful.
 * @retval TPM2_RC_BAD_AUTH If the authentication for an object needed for the
 *         execution fails.
 * @retval TSS2_FAPI_RC_AUTHORIZATION_UNKNOWN if a needed authorization callback
 *         is not defined.
 * @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_FAPI_RC_AUTHORIZATION_FAILED if the authorization attempt fails.
 * @retval TSS2_FAPI_RC_KEY_NOT_FOUND if a key was not found.
 */
TSS2_RC
ifapi_nv_read(
    FAPI_CONTEXT *context,
    uint8_t     **data,
    size_t       *size)
{
    TSS2_RC r;
    UINT16 aux_size;
    TPM2B_MAX_NV_BUFFER *aux_data;
    UINT16 bytesRequested = context->nv_cmd.bytesRequested;
    size_t *numBytes = &context->nv_cmd.numBytes;
    ESYS_TR nv_index = context->nv_cmd.esys_handle;
    IFAPI_OBJECT *auth_object = &context->nv_cmd.auth_object;
    ESYS_TR session;

    switch (context->nv_cmd.nv_read_state) {
    statecase(context->nv_cmd.nv_read_state, NV_READ_INIT);
        LOG_TRACE("NV_READ_INIT");
        context->nv_cmd.rdata = NULL;
        fallthrough;

    statecase(context->nv_cmd.nv_read_state, NV_READ_AUTHORIZE);
        LOG_TRACE("NV_READ_AUTHORIZE");
        r = ifapi_authorize_object(context, auth_object, &session);
        FAPI_SYNC(r, "Authorize NV object.", error_cleanup);

        if (*numBytes > context->nv_buffer_max)
            aux_size = context->nv_buffer_max;
        else
            aux_size = *numBytes;

        /* Prepare the reading from NV ram. */
        r = Esys_NV_Read_Async(context->esys,
                               context->nv_cmd.auth_index,
                               nv_index,
                               session,
                               ESYS_TR_NONE,
                               ESYS_TR_NONE,
                               aux_size,
                               0);
        goto_if_error_reset_state(r, " Fapi_NvRead_Async", error_cleanup);

        context->nv_cmd.nv_read_state = NV_READ_AUTH_SENT;
        context->nv_cmd.bytesRequested = aux_size;

        return TSS2_FAPI_RC_TRY_AGAIN;

    statecase(context->nv_cmd.nv_read_state, NV_READ_AUTH_SENT);
        LOG_TRACE("NV_READ_NULL_AUTH_SENT");
        if (context->nv_cmd.rdata == NULL) {
            /* Allocate the data buffer if not already initialized. */
            LOG_TRACE("Allocate %zu bytes", *numBytes);
            context->nv_cmd.rdata = malloc(*numBytes);
        }
        *data = context->nv_cmd.rdata;
        goto_if_null(*data, "Malloc failed", TSS2_FAPI_RC_MEMORY, error_cleanup);

        r = Esys_NV_Read_Finish(context->esys, &aux_data);

        if (base_rc(r) == TSS2_BASE_RC_TRY_AGAIN)
            return TSS2_FAPI_RC_TRY_AGAIN;

        if (context->nv_cmd.auth_index == ESYS_TR_RH_OWNER  &&
            number_rc(r) == TPM2_RC_BAD_AUTH &&
            auth_object->misc.hierarchy.with_auth == TPM2_NO) {
            /* NULL auth failed, password was used for owner hierarchy, try again. */
            auth_object->misc.hierarchy.with_auth = TPM2_YES;
            context->nv_cmd.nv_read_state =  NV_READ_AUTHORIZE;

            return TSS2_FAPI_RC_TRY_AGAIN;
        }

        goto_if_error_reset_state(r, "FAPI NV_Read_Finish", error_cleanup);

        if (aux_data->size < bytesRequested)
            *numBytes = 0;
        else
            *numBytes -= aux_data->size;
        memcpy(*data + context->nv_cmd.data_idx, &aux_data->buffer[0],
               aux_data->size);
        context->nv_cmd.data_idx += aux_data->size;
        free(aux_data);
        if (*numBytes > 0) {
            statecase(context->nv_cmd.nv_read_state, NV_READ_AUTHORIZE2);
                r = ifapi_authorize_object(context, auth_object, &session);
                FAPI_SYNC(r, "Authorize NV object.", error_cleanup);

            /* The reading of the NV data is not completed. The next
            reading will be prepared. */
            if (*numBytes > context->nv_buffer_max)
                aux_size = context->nv_buffer_max;
            else
                aux_size = *numBytes;

            r = Esys_NV_Read_Async(context->esys,
                                   context->nv_cmd.auth_index,
                                   nv_index,
                                   session,
                                   ESYS_TR_NONE,
                                   ESYS_TR_NONE,
                                   aux_size,
                                   context->nv_cmd.data_idx);
            goto_if_error_reset_state(r, "FAPI NV_Read", error_cleanup);
            context->nv_cmd.bytesRequested = aux_size;
            context->nv_cmd.nv_read_state = NV_READ_AUTH_SENT;
            return TSS2_FAPI_RC_TRY_AGAIN;
        } else {
            *size = context->nv_cmd.data_idx;
            context->nv_cmd.nv_read_state = NV_READ_INIT;
            LOG_DEBUG("success");
            r = TSS2_RC_SUCCESS;
            break;
        }
    statecasedefault(context->nv_cmd.nv_read_state);
    }

error_cleanup:
    return r;
}

#define min(X,Y) (X>Y)?Y:X

/** State machine to retrieve random data from TPM.
 *
 * If the buffer size exceeds the maximum size, several ESAPI calls are made.
 *
 * @param[in,out] context for storing all state information.
 * @param[in] numBytes Number of random bytes to be computed.
 * @param[out] data The random data.
 *
 * @retval TSS2_RC_SUCCESS If random data can be computed.
 * @retval TSS2_ESYS_RC_* possible error codes of ESAPI.
 * @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.
 * @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.
 */
TSS2_RC
ifapi_get_random(FAPI_CONTEXT *context, size_t numBytes, uint8_t **data)
{
    TSS2_RC r;
    TPM2B_DIGEST *aux_data = NULL;

    switch (context->get_random_state) {
    statecase(context->get_random_state, GET_RANDOM_INIT);
        context->get_random.numBytes = numBytes;
        context->get_random.data = calloc(context->get_random.numBytes, 1);
        context->get_random.idx = 0;
        return_if_null(context->get_random.data, "FAPI out of memory.",
                       TSS2_FAPI_RC_MEMORY);

        /* Prepare the creation of random data. */
        r = Esys_GetRandom_Async(context->esys,
                                 context->session1,
                                 ESYS_TR_NONE, ESYS_TR_NONE,
                                 min(context->get_random.numBytes, sizeof(TPMU_HA)));
        goto_if_error_reset_state(r, "FAPI GetRandom", error_cleanup);
        fallthrough;

    statecase(context->get_random_state, GET_RANDOM_SENT);
        r = Esys_GetRandom_Finish(context->esys, &aux_data);
        return_try_again(r);
        goto_if_error_reset_state(r, "FAPI GetRandom_Finish", error_cleanup);

        if (aux_data -> size > context->get_random.numBytes) {
            goto_error(r, TSS2_FAPI_RC_BAD_VALUE, "TPM returned too many bytes",
                       error_cleanup);
        }

        /* Save created random data. */
        memcpy(context->get_random.data + context->get_random.idx, &aux_data->buffer[0],
               aux_data->size);
        context->get_random.numBytes -= aux_data->size;
        context->get_random.idx += aux_data->size;
        Esys_Free(aux_data);
        aux_data = NULL;
        if (context->get_random.numBytes > 0) {

            /* Continue creaion of random data if needed. */
            r = Esys_GetRandom_Async(context->esys, context->session1, ESYS_TR_NONE,
                                     ESYS_TR_NONE, min(context->get_random.numBytes, sizeof(TPMU_HA)));
            goto_if_error_reset_state(r, "FAPI GetRandom", error_cleanup);

            return TSS2_FAPI_RC_TRY_AGAIN;
        }
        break;

    statecasedefault(context->get_random_state);
    }

    *data = context->get_random.data;

    LOG_DEBUG("success");
    context->get_random_state = GET_RANDOM_INIT;
    return TSS2_RC_SUCCESS;

error_cleanup:
    if (aux_data)
        Esys_Free(aux_data);
    context->get_random_state = GET_RANDOM_INIT;
    if (context->get_random.data != NULL)
        SAFE_FREE(context->get_random.data);
    return r;
}

/** Load a key and initialize profile and session for ESAPI execution.
 *
 * This state machine prepares the session for key loading. Some
 * session related parameters will be taken from profile.
 *
 * @param[in,out] context The FAPI_CONTEXT.
 * @param[in]     keyPath the key path without the parent directories
 *                of the key store. (e.g. HE/EK, HS/SRK/mykey)
 * @param[out]    key_object The callee allocated internal representation
 *                of a key object.
 *
 * @retval TSS2_RC_SUCCESS If the key was loaded successfully.
 * @retval TSS2_ESYS_RC_* possible error codes of ESAPI.
 * @retval TSS2_FAPI_RC_MEMORY if not enough memory can be allocated.
 * @retval TSS2_FAPI_RC_GENERAL_FAILURE If an internal error occurs, which is
 *         not covered by other return codes.
 * @retval TSS2_FAPI_RC_BAD_VALUE If wrong values are detected during execution.
 * @retval TSS2_FAPI_RC_IO_ERROR If an error occurs during access to the object
 *         store.
 * @retval TSS2_FAPI_RC_PATH_NOT_FOUND If a policy or key was not found.
 * @retval TSS2_FAPI_RC_POLICY_UNKNOWN If policy search for a certain policy digest was
 *         not successful.
 * @retval TPM2_RC_BAD_AUTH If the authentication for an object needed for policy
 *         execution fails.
 * @retval TSS2_FAPI_RC_AUTHORIZATION_UNKNOWN if a needed authorization callback
           is not defined.
 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
 * @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_FAPI_RC_KEY_NOT_FOUND if a key was not found.
 * @retval TSS2_FAPI_RC_AUTHORIZATION_FAILED if the authorization attempt fails.
 * @retval TSS2_FAPI_RC_NOT_PROVISIONED FAPI was not provisioned.
 * @retval TSS2_FAPI_RC_BAD_PATH if the path is used in inappropriate context
 *         or contains illegal characters.
 */
TSS2_RC
ifapi_load_key(
    FAPI_CONTEXT  *context,
    char    const *keyPath,
    IFAPI_OBJECT **key_object)
{
    TSS2_RC r;
    const IFAPI_PROFILE *profile;

    return_if_null(keyPath, "Bad reference for key path.",
                   TSS2_FAPI_RC_BAD_REFERENCE);

    switch (context->Key_Sign.state) {
    statecase(context->Key_Sign.state, SIGN_INIT);
        context->Key_Sign.keyPath = keyPath;

        /* Prepare the session creation. */
        r = ifapi_get_sessions_async(context,
                                     IFAPI_SESSION_GENEK | IFAPI_SESSION1,
                                     TPMA_SESSION_DECRYPT, 0);
        goto_if_error_reset_state(r, "Create sessions", error_cleanup);
        fallthrough;

    statecase(context->Key_Sign.state, SIGN_WAIT_FOR_SESSION);
        r = ifapi_profiles_get(&context->profiles, context->Key_Sign.keyPath, &profile);
        goto_if_error_reset_state(r, "Reading profile data", error_cleanup);

        r = ifapi_get_sessions_finish(context, profile, profile->nameAlg);
        return_try_again(r);
        goto_if_error_reset_state(r, " FAPI create session", error_cleanup);

        /* Prepare the key loading. */
        r = ifapi_load_keys_async(context, context->Key_Sign.keyPath);
        goto_if_error(r, "Load keys.", error_cleanup);
        fallthrough;

    statecase(context->Key_Sign.state, SIGN_WAIT_FOR_KEY);
        r = ifapi_load_keys_finish(context, IFAPI_FLUSH_PARENT,
                                   &context->Key_Sign.handle,
                                   key_object);
        return_try_again(r);
        goto_if_error_reset_state(r, " Load key.", error_cleanup);

        context->Key_Sign.state = SIGN_INIT;
        break;

    statecasedefault(context->Key_Sign.state);
    }

error_cleanup:
    return r;
}

/** State machine for signing operation.
 *
 * The key used for signing will be authorized and the signing of the passed data
 * will be executed.
 *
 * @param[in,out] context The FAPI_CONTEXT.
 * @param[in]     sig_key_object The Fapi key object which will be used to
 *                sign the passed digest.
 * @param[in]     padding is the padding algorithm used. Possible values are RSA_SSA,
 *                RSA_PPSS (case insensitive). padding MAY be NULL.
 * @param[in]     digest is the data to be signed, already hashed.
 *                digest MUST NOT be NULL.
 * @param[out]    tpm_signature returns the signature in binary form (DER format).
 *                tpm_signature MUST NOT be NULL (callee-allocated).
 * @param[out]    publicKey is the public key of the signing key in PEM format.
 *                publicKey is callee allocated and MAY be NULL.
 * @param[out]    certificate is the certificate associated with the signing key
 *                in PEM format. certificate MAY be NULL.
 *
 * @retval TSS2_RC_SUCCESS If the signing was successful.
 * @retval TSS2_ESYS_RC_* possible error codes of ESAPI.
 * @retval TSS2_FAPI_RC_MEMORY if not enough memory can be allocated.
 * @retval TSS2_FAPI_RC_GENERAL_FAILURE If an internal error occurs, which is
 *         not covered by other return codes.
 * @retval TSS2_FAPI_RC_BAD_VALUE If wrong values are detected during execution.
 * @retval TSS2_FAPI_RC_IO_ERROR If an error occurs during access to the policy
 *         store.
 * @retval TSS2_FAPI_RC_PATH_NOT_FOUND If a policy for a certain path was not found.
 * @retval TSS2_FAPI_RC_POLICY_UNKNOWN If policy search for a certain policy digest was
 *         not successful.
 * @retval TSS2_FAPI_RC_BAD_TEMPLATE In a invalid policy is loaded during execution.
 * @retval TPM2_RC_BAD_AUTH If the authentication for an object needed for policy
 *         execution fails.
 * @retval TSS2_FAPI_RC_AUTHORIZATION_UNKNOWN if a needed authorization callback
 *         is not defined.
 * @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_FAPI_RC_AUTHORIZATION_FAILED if the authorization attempt fails.
 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
 * @retval TSS2_FAPI_RC_KEY_NOT_FOUND if a key was not found.
 */
TSS2_RC
ifapi_key_sign(
    FAPI_CONTEXT     *context,
    IFAPI_OBJECT     *sig_key_object,
    char const       *padding,
    TPM2B_DIGEST     *digest,
    TPMT_SIGNATURE  **tpm_signature,
    char            **publicKey,
    char            **certificate)
{
    TSS2_RC r;
    TPMT_SIG_SCHEME sig_scheme;
    ESYS_TR session;

    TPMT_TK_HASHCHECK hash_validation = {
        .tag = TPM2_ST_HASHCHECK,
        .hierarchy = TPM2_RH_OWNER,
    };
    memset(&hash_validation.digest, 0, sizeof(TPM2B_DIGEST));

    switch (context->Key_Sign.state) {
    statecase(context->Key_Sign.state, SIGN_INIT);
        sig_key_object = context->Key_Sign.key_object;

        r = ifapi_authorize_object(context, sig_key_object, &session);
        FAPI_SYNC(r, "Authorize signature key.", cleanup);

        context->policy.session = session;

        r = ifapi_get_sig_scheme(context, sig_key_object, padding, digest, &sig_scheme);
        goto_if_error(r, "Get signature scheme", cleanup);

        /* Prepare the signing operation. */
        r = Esys_Sign_Async(context->esys,
                            context->Key_Sign.handle,
                            session,
                            ESYS_TR_NONE, ESYS_TR_NONE,
                            digest,
                            &sig_scheme,
                            &hash_validation);
        goto_if_error(r, "Error: Sign", cleanup);
        fallthrough;

    statecase(context->Key_Sign.state, SIGN_AUTH_SENT);
        context->Key_Sign.signature = NULL;
        r = Esys_Sign_Finish(context->esys,
                             &context->Key_Sign.signature);
        return_try_again(r);
        ifapi_flush_policy_session(context, context->policy.session, r);
        goto_if_error(r, "Error: Sign", cleanup);

        /* Prepare the flushing of the signing key. */
        if (!sig_key_object->misc.key.persistent_handle) {
            r = Esys_FlushContext_Async(context->esys, context->Key_Sign.handle);
            goto_if_error(r, "Error: FlushContext", cleanup);
        }
        fallthrough;

    statecase(context->Key_Sign.state, SIGN_WAIT_FOR_FLUSH);
        if (!sig_key_object->misc.key.persistent_handle) {
            r = Esys_FlushContext_Finish(context->esys);
            return_try_again(r);
            goto_if_error(r, "Error: Sign", cleanup);
        }

        int pem_size;
        if (publicKey) {
            /* Convert internal key object to PEM format. */
            r = ifapi_pub_pem_key_from_tpm(&sig_key_object->misc.key.public,
                                                publicKey,
                                                &pem_size);
            goto_if_error(r, "Conversion pub key to PEM failed", cleanup);
        }
        context->Key_Sign.handle = ESYS_TR_NONE;
        *tpm_signature = context->Key_Sign.signature;
        if (certificate) {
            if (context->Key_Sign.key_object->misc.key.certificate) {
                *certificate = strdup(context->Key_Sign.key_object->misc.key.certificate);
                goto_if_null(*certificate, "Out of memory.",
                             TSS2_FAPI_RC_MEMORY, cleanup);
            } else {
                strdup_check(*certificate, "", r, cleanup);
            }
        }
        context->Key_Sign.state = SIGN_INIT;
        LOG_TRACE("success");
        r = TSS2_RC_SUCCESS;
        break;

    statecasedefault(context->Key_Sign.state);
    }

cleanup:
    if (context->Key_Sign.handle != ESYS_TR_NONE)
        Esys_FlushContext(context->esys, context->Key_Sign.handle);
    ifapi_cleanup_ifapi_object(context->Key_Sign.key_object);
    return r;
}

/** Get json encoding for FAPI object.
 *
 * A json representation which can be used for exporting of a FAPI object will
 * be created.
 *
 * @param[in]   context The FAPI_CONTEXT.
 * @param[in]   object The object to be serialized.
 * @param[out]  json_string The json string created by the deserialzation
 *              function (callee-allocated).
 *
 * @retval TSS2_RC_SUCCESS If the serialization was successful.
 * @retval TSS2_FAPI_RC_MEMORY if not enough memory can be allocated.
 * @retval TSS2_FAPI_RC_BAD_VALUE If wrong values are detected during
 *         serialization.
 * @retval TSS2_FAPI_RC_BAD_REFERENCE If a NULL pointer was passed for
 *         the object.
 * @retval TSS2_FAPI_RC_GENERAL_FAILURE if an internal error occurred.
 * @retval TSS2_ESYS_RC_* possible error codes of ESAPI.
 */
TSS2_RC
ifapi_get_json(FAPI_CONTEXT *context, IFAPI_OBJECT *object, char **json_string)
{
    TSS2_RC r = TSS2_RC_SUCCESS;
    json_object *jso = NULL;

    /* Perform esys serialization if necessary */
    r = ifapi_esys_serialize_object(context->esys, object);
    goto_if_error(r, "Prepare serialization", cleanup);

    r = ifapi_json_IFAPI_OBJECT_serialize(object, &jso);
    return_if_error(r, "Serialize duplication object");

    *json_string = strdup(json_object_to_json_string_ext(jso,
                          JSON_C_TO_STRING_PRETTY));
    goto_if_null2(*json_string, "Converting json to string", r, TSS2_FAPI_RC_MEMORY,
                  cleanup);

cleanup:
    if (jso)
        json_object_put(jso);
    return r;
}

/** Serialize persistent objects into buffer of keystore object.
 *
 * NV objects and persistent keys will serialized via the ESYS API to
 * enable reconstruction durinng loading from keystore.
 *
 * @param[in]     ectx The ESAPI context.
 * @param[in,out] object  The nv object or the key.
 * @retval TSS2_RC_SUCCESS if the function call was a success.
 * @retval TSS2_FAPI_RC_GENERAL_FAILURE if an internal error occured.
 */
TSS2_RC
ifapi_esys_serialize_object(ESYS_CONTEXT *ectx, IFAPI_OBJECT *object)
{
    TSS2_RC r = TSS2_RC_SUCCESS;
    IFAPI_KEY *key_object = NULL;
    IFAPI_NV *nv_object;

    switch (object->objectType) {
    case IFAPI_NV_OBJ:
        nv_object = &object->misc.nv;
        if (nv_object->serialization.buffer != NULL) {
            /* Cleanup old buffer */
            Fapi_Free(nv_object->serialization.buffer);
            nv_object->serialization.buffer = NULL;
        }
        r = Esys_TR_Serialize(ectx, object->handle,
                              &nv_object->serialization.buffer,
                              &nv_object->serialization.size);
        return_if_error(r, "Error serialize esys object");
        break;

    case IFAPI_KEY_OBJ:
        key_object = &object->misc.key;
        key_object->serialization.size = 0;
        if (key_object->serialization.buffer != NULL) {
            /* Cleanup old buffer */
            Fapi_Free(key_object->serialization.buffer);
            key_object->serialization.buffer = NULL;
        }
        if (object->handle != ESYS_TR_NONE && key_object->persistent_handle) {
            key_object->serialization.buffer = NULL;
            r = Esys_TR_Serialize(ectx, object->handle,
                                  &key_object->serialization.buffer,
                                  &key_object->serialization.size);
            return_if_error(r, "Error serialize esys object");
        }
        break;

    default:
        /* Nothing to be done */
        break;
    }
    return TSS2_RC_SUCCESS;
}

 /** Initialize the part of an IFAPI_OBJECT  which is not serialized.
  *
  * For persistent objects the correspodning ESYS object will be created.
  *
  * @param[in,out] ectx The ESYS context.
  * @param[out] object the deserialzed binary object.
  * @retval TSS2_RC_SUCCESS if the function call was a success.
  * @retval TSS2_FAPI_RC_BAD_VALUE if the json object can't be deserialized.
  */
TSS2_RC
ifapi_initialize_object(
    ESYS_CONTEXT *ectx,
    IFAPI_OBJECT *object)
{
    TSS2_RC r = TSS2_RC_SUCCESS;
    ESYS_TR handle;

    switch (object->objectType) {
    case IFAPI_NV_OBJ:
        if (object->misc.nv.serialization.size > 0) {
            r = Esys_TR_Deserialize(ectx, &object->misc.nv.serialization.buffer[0],
                                    object->misc.nv.serialization.size, &handle);
            goto_if_error(r, "Error dserialize esys object", cleanup);
        } else {
            handle = ESYS_TR_NONE;
        }
        object->authorization_state = AUTH_INIT;
        object->handle = handle;
        break;

    case IFAPI_KEY_OBJ:
        if (object->misc.key.serialization.size > 0) {
            r = Esys_TR_Deserialize(ectx, &object->misc.key.serialization.buffer[0],
                                    object->misc.key.serialization.size, &handle);
            goto_if_error(r, "Error deserialize esys object", cleanup);
        } else {
            handle = ESYS_TR_NONE;
        }
        object->authorization_state = AUTH_INIT;
        object->handle = handle;
        break;

    default:
        object->authorization_state = AUTH_INIT;
        break;
    }

    return r;

cleanup:
    SAFE_FREE(object->policy);
    return r;
}

/** Prepare key creation with an auth value.
 *
 * The auth value will be copied int the FAPI context for later use in key creation.
 *
 * @param[in,out] context The FAPI_CONTEXT.
 * @param[in]     keyPath the key path without the parent directories
 *                of the key store. (e.g. HE/EK, HS/SRK/mykey)
 * @param[in]     policyPath identifies the policy to be associated with the new key.
 *                policyPath MAY be NULL. If policyPath is NULL then no policy will
 *                be associated with the key.
 * @param[in]     authValue The authentication value of the key.
 *
 * @retval TSS2_RC_SUCCESS If the preparation was successful.
 * @retval TSS2_FAPI_RC_PATH_ALREADY_EXISTS If the object with does already exist in
 *         keystore.
 * @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.
 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
 * @retval TSS2_FAPI_RC_NO_TPM if FAPI was initialized in no-TPM-mode via its
 *         config file.
 * @retval TSS2_FAPI_RC_BAD_SEQUENCE if the context has an asynchronous
 *         operation already pending.
 * @retval TSS2_FAPI_RC_BAD_PATH if the path is used in inappropriate context
 *         or contains illegal characters.
 * @retval TSS2_FAPI_RC_PATH_NOT_FOUND if a FAPI object path was not found
 *         during authorization.
 */
TSS2_RC
ifapi_key_create_prepare_auth(
    FAPI_CONTEXT  *context,
    char   const *keyPath,
    char   const *policyPath,
    char   const *authValue)
{
    TSS2_RC r;

    memset(&context->cmd.Key_Create.inSensitive, 0, sizeof(TPM2B_SENSITIVE_CREATE));
    if (authValue) {
        /* Copy the auth value */
        if (strlen(authValue) > sizeof(TPMU_HA)) {
            return_error(TSS2_FAPI_RC_BAD_VALUE, "Password too long.");
        }
        memcpy(&context->cmd.Key_Create.inSensitive.sensitive.userAuth.buffer,
               authValue, strlen(authValue));
        context->cmd.Key_Create.inSensitive.sensitive.userAuth.size = strlen(authValue);
    }
    context->cmd.Key_Create.gen_sensitive_random = false;
    context->cmd.Key_Create.inSensitive.sensitive.data.size = 0;
    r = ifapi_key_create_prepare(context, keyPath, policyPath);
    return r;
}

/** Prepare key creation with an auth value and sensitive data.
 *
 * The auth value and the sensitive data will be copied int the FAPI context
 * for later use in key creation.
 *
 * @param[in,out] context The FAPI_CONTEXT.
 * @param[in]     keyPath the key path without the parent directories
 *                of the key store. (e.g. HE/EK, HS/SRK/mykey)
 * @param[in]     policyPath identifies the policy to be associated with the new key.
 *                policyPath MAY be NULL. If policyPath is NULL then no policy will
 *                be associated with the key.
 * @param[in]     dataSize The size of the sensitive data.
 * @param[in]     authValue The authentication value of the key.
 * @param[in]     data The sensitive data.
 *
 * @retval TSS2_RC_SUCCESS If the preparation was successful.
 * @retval TSS2_FAPI_RC_PATH_ALREADY_EXISTS If the object with does already exist in
 *         keystore.
 * @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.
 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
 * @retval TSS2_FAPI_RC_NO_TPM if FAPI was initialized in no-TPM-mode via its
 *         config file.
 * @retval TSS2_FAPI_RC_BAD_SEQUENCE if the context has an asynchronous
 *         operation already pending.
 * @retval TSS2_FAPI_RC_BAD_PATH if the path is used in inappropriate context
 *         or contains illegal characters.
 * @retval TSS2_FAPI_RC_PATH_NOT_FOUND if a FAPI object path was not found
 *         during authorization.
 */
TSS2_RC
ifapi_key_create_prepare_sensitive(
    FAPI_CONTEXT  *context,
    char    const *keyPath,
    char    const *policyPath,
    size_t         dataSize,
    char    const *authValue,
    uint8_t const *data)
{
    TSS2_RC r;

    memset(&context->cmd.Key_Create.inSensitive, 0, sizeof(TPM2B_SENSITIVE_CREATE));
    if (dataSize > sizeof(context->cmd.Key_Create.inSensitive.sensitive.data.buffer)
        || dataSize == 0) {
        return_error(TSS2_FAPI_RC_BAD_VALUE, "Data too big or equal zero.");
    }
    if (data) {
        /* Copy the sensitive data */
        context->cmd.Key_Create.gen_sensitive_random = false;
        memcpy(&context->cmd.Key_Create.inSensitive.sensitive.data.buffer,
               data, dataSize);
    } else {
        context->cmd.Key_Create.gen_sensitive_random = true;
    }
    context->cmd.Key_Create.inSensitive.sensitive.data.size = dataSize;
    if (authValue) {
        /* Copy the auth value. */
        if (strlen(authValue) > sizeof(TPMU_HA)) {
            return_error(TSS2_FAPI_RC_BAD_VALUE, "Password too long.");
        }
        memcpy(&context->cmd.Key_Create.inSensitive.sensitive.userAuth.buffer,
               authValue, strlen(authValue));
        context->cmd.Key_Create.inSensitive.sensitive.userAuth.size = strlen(authValue);
    }
    r = ifapi_key_create_prepare(context, keyPath, policyPath);
    return r;
}

/** Prepare key creation if possible.
 *
 * It will be checked whether the object already exists in key store and the FAPI context
 * will be initialized appropriate for key creation.
 *
 * @param[in,out] context The FAPI_CONTEXT.
 * @param[in]     keyPath the key path without the parent directories
 *                of the key store. (e.g. HE/EK, HS/SRK/mykey)
 * @param[in]     policyPath identifies the policy to be associated with the new key.
 *                policyPath MAY be NULL. If policyPath is NULL then no policy will
 *                be associated with the key.
 *
 * @retval TSS2_RC_SUCCESS If the preparation was successful.
 * @retval TSS2_FAPI_RC_PATH_ALREADY_EXISTS If the object with does already exist in
 *         keystore.
 * @retval TSS2_FAPI_RC_MEMORY if not enough memory can be allocated.
 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
 * @retval TSS2_FAPI_RC_NO_TPM if FAPI was initialized in no-TPM-mode via its
 *         config file.
 * @retval TSS2_FAPI_RC_BAD_SEQUENCE if the context has an asynchronous
 *         operation already pending.
 * @retval TSS2_FAPI_RC_BAD_VALUE if an invalid value was passed into
 *         the function.
 * @retval TSS2_FAPI_RC_BAD_PATH if the path is used in inappropriate context
 *         or contains illegal characters.
 * @retval TSS2_FAPI_RC_PATH_NOT_FOUND if a FAPI object path was not found
 *         during authorization.
 */
TSS2_RC
ifapi_key_create_prepare(
    FAPI_CONTEXT  *context,
    char   const *keyPath,
    char   const *policyPath)
{
    TSS2_RC r;
    IFAPI_OBJECT *object = &context->cmd.Key_Create.object;
    NODE_STR_T *path_list = NULL;

    LOG_TRACE("call");
    r = ifapi_session_init(context);
    return_if_error(r, "Initialize Key_Create");

    /* First check whether an existing object would be overwritten */
    r = ifapi_keystore_check_overwrite(&context->keystore, &context->io,
                                       keyPath);
    return_if_error2(r, "Check overwrite %s", keyPath);

    context->srk_handle = 0;

    /* Clear the memory used for the the new key object */
    memset(&context->cmd.Key_Create.outsideInfo, 0, sizeof(TPM2B_DATA));
    memset(&context->cmd.Key_Create.creationPCR, 0, sizeof(TPML_PCR_SELECTION));
    memset(object, 0, sizeof(IFAPI_OBJECT));

    strdup_check(context->cmd.Key_Create.policyPath, policyPath, r, error);
    strdup_check(context->cmd.Key_Create.keyPath, keyPath, r, error);
    r = get_explicit_key_path(&context->keystore, keyPath, &path_list);
    return_if_error(r, "Compute explicit path.");

    context->loadKey.path_list = path_list;
    char *file;
    r = ifapi_path_string(&file, NULL, path_list, NULL);
    goto_if_error(r, "Compute explicit path.", error);

    LOG_DEBUG("Explicit key path: %s", file);

    free(file);

    context->cmd.Key_Create.state = KEY_CREATE_INIT;

    return TSS2_RC_SUCCESS;

error:
    free_string_list(path_list);
    return r;
}

/** State machine for key creation.
 *
 * The function for the preparation of the key have to called before the state machine can
 * be activated. The linked list for the used directories must be available in the
 * FAPI context.
 * It will be checked whether the object already exists in key store and the FAPI context
 * will be initialized appropriate for key creation.
 *
 * @param[in,out] context The FAPI_CONTEXT.
 * @param[in] template The template which defines the key attributes and whether the
 *            key will be persistent.
 *
 * @retval TSS2_RC_SUCCESS If the key could be generated.
 * @retval TSS2_ESYS_RC_* possible error codes of ESAPI.
 * @retval TSS2_FAPI_RC_MEMORY if not enough memory can be allocated.
 * @retval TSS2_FAPI_RC_GENERAL_FAILURE If an internal error occurs, which is
 *         not covered by other return codes.
 * @retval TSS2_FAPI_RC_BAD_VALUE If wrong values are detected during execution.
 * @retval TSS2_FAPI_RC_IO_ERROR If an error occurs during access to the policy
 *         store.
 * @retval TSS2_FAPI_RC_PATH_NOT_FOUND If an object needed for creation or
           authentication was not found.
 * @retval TSS2_FAPI_RC_POLICY_UNKNOWN If policy search for a certain policy digest was
 *         not successful.
 * @retval TPM2_RC_BAD_AUTH If the authentication for an object needed for creation
 *         fails.
 * @retval TSS2_FAPI_RC_AUTHORIZATION_UNKNOWN if a needed authorization callback
 *         is not defined.
 * @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_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
 * @retval TSS2_FAPI_RC_NOT_PROVISIONED FAPI was not provisioned.
 * @retval TSS2_FAPI_RC_KEY_NOT_FOUND if a key was not found.
 * @retval TSS2_FAPI_RC_BAD_PATH if the path is used in inappropriate context
 *         or contains illegal characters.
 * @retval TSS2_FAPI_RC_AUTHORIZATION_FAILED if the authorization attempt fails.
 * @retval TSS2_FAPI_RC_PATH_ALREADY_EXISTS if the object already exists in object store.
 */
TSS2_RC
ifapi_key_create(
    FAPI_CONTEXT *context,
    IFAPI_KEY_TEMPLATE *template)
{
    TSS2_RC r;
    size_t path_length;
    NODE_STR_T *path_list = context->loadKey.path_list;
    TPM2B_PUBLIC *outPublic = NULL;
    TPM2B_PRIVATE *outPrivate = NULL;
    TPM2B_CREATION_DATA *creationData = NULL;
    TPM2B_DIGEST *creationHash = NULL;
    TPMT_TK_CREATION *creationTicket = NULL;
    IFAPI_OBJECT *object = &context->cmd.Key_Create.object;
    IFAPI_OBJECT *hierarchy = &context->cmd.Key_Create.hierarchy;
    ESYS_TR auth_session;
    uint8_t *random_data = NULL;

    LOG_TRACE("call");

    switch (context->cmd.Key_Create.state) {
    statecase(context->cmd.Key_Create.state, KEY_CREATE_INIT);
        context->cmd.Key_Create.public_templ = *template;
        context->loadKey.auth_object.handle = ESYS_TR_NONE;

        /* Profile name is first element of the explicit path list */
        char *profile_name = context->loadKey.path_list->str;
        r = ifapi_profiles_get(&context->profiles, profile_name, &context->cmd.Key_Create.profile);
        goto_if_error_reset_state(r, "Retrieving profile data", error_cleanup);

        if (context->cmd.Key_Create.inSensitive.sensitive.data.size > 0) {
            /* A keyed hash object sealing sensitive data will be created */
            context->cmd.Key_Create.public_templ.public.publicArea.type = TPM2_ALG_KEYEDHASH;
            context->cmd.Key_Create.public_templ.public.publicArea.nameAlg =
                    context->cmd.Key_Create.profile->nameAlg;
            context->cmd.Key_Create.public_templ.public.publicArea.parameters.keyedHashDetail.scheme.scheme =
            TPM2_ALG_NULL;
        } else {
            r = ifapi_merge_profile_into_template(context->cmd.Key_Create.profile,
                                                  &context->cmd.Key_Create.public_templ);
            goto_if_error_reset_state(r, "Merge profile", error_cleanup);
        }

        if (context->cmd.Key_Create.policyPath
                && strcmp(context->cmd.Key_Create.policyPath, "") != 0)
            context->cmd.Key_Create.state = KEY_CREATE_CALCULATE_POLICY;
        /* else jump over to KEY_CREATE_WAIT_FOR_SESSION below */
    /* FALLTHRU */

    case KEY_CREATE_CALCULATE_POLICY:
        if (context->cmd.Key_Create.state == KEY_CREATE_CALCULATE_POLICY) {
            r = ifapi_calculate_tree(context, context->cmd.Key_Create.policyPath,
                                     &context->policy.policy,
                                     context->cmd.Key_Create.public_templ.public.publicArea.nameAlg,
                                     &context->policy.digest_idx,
                                     &context->policy.hash_size);
            return_try_again(r);
            goto_if_error2(r, "Calculate policy tree %s", error_cleanup,
                           context->cmd.Key_Create.policyPath);

            /* Store the calculated policy in the key object */
            object->policy = calloc(1, sizeof(TPMS_POLICY));
            return_if_null(object->policy, "Out of memory",
                    TSS2_FAPI_RC_MEMORY);
            *(object->policy) = context->policy.policy;

            context->cmd.Key_Create.public_templ.public.publicArea.authPolicy.size =
                context->policy.hash_size;
            memcpy(&context->cmd.Key_Create.public_templ.public.publicArea.authPolicy.buffer[0],
                   &context->policy.policy.policyDigests.digests[context->policy.digest_idx].digest,
                   context->policy.hash_size);
        }
        r = ifapi_get_sessions_async(context,
                                     IFAPI_SESSION_GENEK | IFAPI_SESSION1,
                                     TPMA_SESSION_ENCRYPT | TPMA_SESSION_DECRYPT, 0);
        goto_if_error_reset_state(r, "Create sessions", error_cleanup);
        fallthrough;

    statecase(context->cmd.Key_Create.state, KEY_CREATE_WAIT_FOR_SESSION);
        LOG_TRACE("KEY_CREATE_WAIT_FOR_SESSION");
        r = ifapi_get_sessions_finish(context, context->cmd.Key_Create.profile,
                                      context->cmd.Key_Create.profile->nameAlg);
        return_try_again(r);
        goto_if_error_reset_state(r, " FAPI create session", error_cleanup);
        fallthrough;

    statecase(context->cmd.Key_Create.state, KEY_CREATE_WAIT_FOR_RANDOM);
        if (context->cmd.Key_Create.gen_sensitive_random) {
            r = ifapi_get_random(context,
                                 context->cmd.Key_Create.inSensitive.sensitive.data.size,
                                 &random_data);
            return_try_again(r);
            goto_if_error_reset_state(r, "FAPI GetRandom", error_cleanup);

            /* Copy the sensitive data */
            memcpy(&context->cmd.Key_Create.inSensitive.sensitive.data.buffer,
                   random_data,
                   context->cmd.Key_Create.inSensitive.sensitive.data.size);
            SAFE_FREE(random_data);
        }
        path_length = ifapi_path_length(path_list);
        r = ifapi_load_key_async(context, path_length - 1);
        goto_if_error(r, "LoadKey async", error_cleanup);
        fallthrough;

    statecase(context->cmd.Key_Create.state, KEY_CREATE_WAIT_FOR_PARENT);
        LOG_TRACE("KEY_CREATE_WAIT_FOR_PARENT");
        r = ifapi_load_key_finish(context, IFAPI_FLUSH_PARENT);
        return_try_again(r);
        goto_if_error(r, "LoadKey finish", error_cleanup);
        fallthrough;

    statecase(context->cmd.Key_Create.state, KEY_CREATE_WAIT_FOR_AUTHORIZATION);
        r = ifapi_authorize_object(context, &context->loadKey.auth_object, &auth_session);
        FAPI_SYNC(r, "Authorize key.", error_cleanup);

        r = Esys_Create_Async(context->esys, context->loadKey.auth_object.handle,
                              auth_session,
                              ESYS_TR_NONE, ESYS_TR_NONE,
                              &context->cmd.Key_Create.inSensitive,
                              &context->cmd.Key_Create.public_templ.public,
                              &context->cmd.Key_Create.outsideInfo,
                              &context->cmd.Key_Create.creationPCR);
        goto_if_error(r, "Create_Async", error_cleanup);
        fallthrough;

    statecase(context->cmd.Key_Create.state, KEY_CREATE_AUTH_SENT);
        r = Esys_Create_Finish(context->esys, &outPrivate, &outPublic, &creationData,
                               &creationHash, &creationTicket);
        try_again_or_error_goto(r, "Key create finish", error_cleanup);

        /* Prepare object for serialization */
        object->system = context->cmd.Key_Create.public_templ.system;
        object->objectType = IFAPI_KEY_OBJ;
        object->misc.key.public = *outPublic;
        object->misc.key.private.size = outPrivate->size;
        object->misc.key.private.buffer = calloc(1, outPrivate->size);
        goto_if_null2( object->misc.key.private.buffer, "Out of memory.", r,
                       TSS2_FAPI_RC_MEMORY, error_cleanup);

        object->misc.key.private.buffer = memcpy(&object->misc.key.private.buffer[0],
                                                 &outPrivate->buffer[0], outPrivate->size);
        object->misc.key.policyInstance = NULL;
        object->misc.key.creationData = *creationData;
        object->misc.key.creationTicket = *creationTicket;
        object->misc.key.description = NULL;
        object->misc.key.certificate = NULL;
        SAFE_FREE(creationData);
        SAFE_FREE(creationTicket);
        SAFE_FREE(creationHash);
        if (context->cmd.Key_Create.inSensitive.sensitive.userAuth.size > 0)
            object->misc.key.with_auth = TPM2_YES;
        else
            object->misc.key.with_auth = TPM2_NO;;
        r = ifapi_get_name(&outPublic->publicArea, &object->misc.key.name);
        goto_if_error(r, "Get key name", error_cleanup);

        SAFE_FREE(outPrivate);
        SAFE_FREE(outPublic);

        if (object->misc.key.public.publicArea.type == TPM2_ALG_RSA)
            object->misc.key.signing_scheme = context->cmd.Key_Create.profile->rsa_signing_scheme;
        else
            object->misc.key.signing_scheme = context->cmd.Key_Create.profile->ecc_signing_scheme;

        fallthrough;

    statecase(context->cmd.Key_Create.state, KEY_CREATE_WAIT_FOR_LOAD_AUTHORIZATION);
        if (template->persistent_handle) {
            r = ifapi_authorize_object(context, &context->loadKey.auth_object, &auth_session);
            FAPI_SYNC(r, "Authorize key.", error_cleanup);

            TPM2B_PRIVATE private;
            private.size = object->misc.key.private.size;
            memcpy(&private.buffer[0], &object->misc.key.private.buffer[0],
                   private.size);

            r = Esys_Load_Async(context->esys, context->loadKey.handle,
                                auth_session,
                                ESYS_TR_NONE, ESYS_TR_NONE,
                                &private,
                                &object->misc.key.public);
            goto_if_error(r, "Load key.", error_cleanup);

        }
        fallthrough;

    statecase(context->cmd.Key_Create.state, KEY_CREATE_WAIT_FOR_KEY);
        if (template->persistent_handle) {
            r = Esys_Load_Finish(context->esys, &context->loadKey.handle);
            return_try_again(r);
            goto_if_error_reset_state(r, "Load", error_cleanup);
        }
        /* Prepare Flushing of key used for authorization */
        if (!context->loadKey.auth_object.misc.key.persistent_handle) {
            r = Esys_FlushContext_Async(context->esys, context->loadKey.auth_object.handle);
            goto_if_error(r, "Flush parent", error_cleanup);
        }
        fallthrough;

    statecase(context->cmd.Key_Create.state, KEY_CREATE_FLUSH1);
        if (!context->loadKey.auth_object.misc.key.persistent_handle) {
            r = Esys_FlushContext_Finish(context->esys);
            try_again_or_error_goto(r, "Flush context", error_cleanup);

            ifapi_cleanup_ifapi_object(&context->loadKey.auth_object);
        }
        if (template->persistent_handle) {
            r = ifapi_keystore_load_async(&context->keystore, &context->io, "/HS");
            return_if_error2(r, "Could not open hierarchy /HS");
        }
        fallthrough;

    statecase(context->cmd.Key_Create.state, KEY_CREATE_WAIT_FOR_HIERARCHY);
        if (template->persistent_handle) {
            r = ifapi_keystore_load_finish(&context->keystore, &context->io, hierarchy);
            return_try_again(r);
            return_if_error(r, "read_finish failed");
            r = ifapi_initialize_object(context->esys, hierarchy);
            goto_if_error_reset_state(r, "Initialize hierarchy object", error_cleanup);

            hierarchy->handle = ESYS_TR_RH_OWNER;
        }
        fallthrough;

    statecase(context->cmd.Key_Create.state, KEY_CREATE_AUTHORIZE_HIERARCHY);
        if (template->persistent_handle) {
            r = ifapi_authorize_object(context, hierarchy, &auth_session);
            FAPI_SYNC(r, "Authorize hierarchy.", error_cleanup);

            object->misc.key.persistent_handle = template->persistent_handle;

            /* Prepare making the loaded key permanent. */
            r = Esys_EvictControl_Async(context->esys, hierarchy->handle,
                                        context->loadKey.handle,
                                        auth_session, ESYS_TR_NONE,
                                        ESYS_TR_NONE,
                                        object->misc.key.persistent_handle);
            goto_if_error(r, "Error Esys EvictControl", error_cleanup);

            ifapi_cleanup_ifapi_object(hierarchy);
        }
        fallthrough;

    statecase(context->cmd.Key_Create.state, KEY_CREATE_WAIT_FOR_EVICT_CONTROL);
        if (template->persistent_handle) {
            /* Prepare making the loaded key permanent. */
            r = Esys_EvictControl_Finish(context->esys, &object->handle);
            return_try_again(r);
            goto_if_error(r, "Evict control failed", error_cleanup);
        }

        fallthrough;

    statecase(context->cmd.Key_Create.state, KEY_CREATE_FLUSH2);
        /* Flush the key which was evicted. */
        if (template->persistent_handle) {
            r = ifapi_flush_object(context, context->loadKey.handle);
            return_try_again(r);
            goto_if_error(r, "Flush key", error_cleanup);
        }

        fallthrough;

    statecase(context->cmd.Key_Create.state, KEY_CREATE_WRITE_PREPARE);
        if (template->persistent_handle) {
            /* Compute the serialization, which will be used for the
               reconstruction of the key object. */
            SAFE_FREE(object->misc.key.serialization.buffer);
            r = Esys_TR_Serialize(context->esys, object->handle,
                                  &object->misc.key.serialization.buffer,
                                  &object->misc.key.serialization.size);
            goto_if_error(r, "Serialize object", error_cleanup);
        }

        /* Perform esys serialization if necessary */
        r = ifapi_esys_serialize_object(context->esys, object);
        goto_if_error(r, "Prepare serialization", error_cleanup);

        /* Check whether object already exists in key store.*/
        r = ifapi_keystore_object_does_not_exist(&context->keystore,
                                                 context->cmd.Key_Create.keyPath,
                                                 object);
        goto_if_error_reset_state(r, "Could not write: %s", error_cleanup,
                                  context->cmd.Key_Create.keyPath);

        /* Start writing the object to the key store */
        r = ifapi_keystore_store_async(&context->keystore, &context->io,
                                       context->cmd.Key_Create.keyPath, object);
        goto_if_error_reset_state(r, "Could not open: %s", error_cleanup,
                                  context->cmd.Key_Create.keyPath);
        ifapi_cleanup_ifapi_object(object);
        fallthrough;

    statecase(context->cmd.Key_Create.state, KEY_CREATE_WRITE);
        /* Finish writing the key to the key store */
        r = ifapi_keystore_store_finish(&context->keystore, &context->io);
        return_try_again(r);
        return_if_error_reset_state(r, "write_finish failed");

        fallthrough;

    statecase(context->cmd.Key_Create.state, KEY_CREATE_CLEANUP);
        r = ifapi_cleanup_session(context);
        try_again_or_error_goto(r, "Cleanup", error_cleanup);

        context->cmd.Key_Create.state = KEY_CREATE_INIT;
        r = TSS2_RC_SUCCESS;
        break;

    statecasedefault(context->cmd.Key_Create.state);
    }

 cleanup:
    free_string_list(context->loadKey.path_list);
    SAFE_FREE(outPublic);
    SAFE_FREE(outPrivate);
    SAFE_FREE(creationData);
    SAFE_FREE(creationHash);
    SAFE_FREE(creationTicket);
    SAFE_FREE(context->cmd.Key_Create.policyPath);
    SAFE_FREE(context->cmd.Key_Create.keyPath);
    SAFE_FREE(random_data);
    ifapi_cleanup_ifapi_object(object);
    ifapi_session_clean(context);
    if  (template->persistent_handle)
        ifapi_cleanup_ifapi_object(hierarchy);
    return r;

 error_cleanup:
    if  (template->persistent_handle)
        ifapi_cleanup_ifapi_object(hierarchy);
    if (context->loadKey.auth_object.handle != ESYS_TR_NONE &&
        !context->loadKey.auth_object.misc.key.persistent_handle) {
        Esys_FlushContext(context->esys, context->loadKey.auth_object.handle);
    }
    goto cleanup;
}

/** Get signature scheme for key.
 *
 * If padding is passed the scheme will be derived from paddint otherwise
 * the scheme form object will be used.
 *
 * @param[in] context The FAPI_CONTEXT.
 * @param[in] object The internal FAPI object of the key.
 * @param[in] padding The strings RSA_SSA or RSA_PSS will be converted
 *            into the TSS constants used for the signing scheme.
 * @param[in] digest The digest size will be used to determine the hashalg
 *            for the signature scheme.
 * @param[out] sig_scheme The computed signature scheme.
 *
 * @retval TSS2_FAPI_RC_BAD_VALUE If the digest size is not appropriate.
 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
 */
TSS2_RC
ifapi_get_sig_scheme(
    FAPI_CONTEXT *context,
    IFAPI_OBJECT *object,
    char const *padding,
    TPM2B_DIGEST *digest,
    TPMT_SIG_SCHEME *sig_scheme)
{
    TPMI_ALG_HASH hash_alg;
    TSS2_RC r;

    if (padding) {
        /* Get hash algorithm from digest size */
        r = ifapi_get_hash_alg_for_size(digest->size, &hash_alg);
        return_if_error2(r, "Invalid digest size.");

        /* Use scheme object from context */
        if (strcasecmp("RSA_SSA", padding) == 0) {
            context->Key_Sign.scheme.scheme = TPM2_ALG_RSASSA;
            context->Key_Sign.scheme.details.rsassa.hashAlg = hash_alg;
        }
        if (strcasecmp("RSA_PSS", padding) == 0) {
            context->Key_Sign.scheme.scheme = TPM2_ALG_RSAPSS;
            context->Key_Sign.scheme.details.rsapss.hashAlg = hash_alg;
        }
        *sig_scheme = context->Key_Sign.scheme;
        return TSS2_RC_SUCCESS;
    } else {
        /* Use scheme defined for object */
        *sig_scheme = object->misc.key.signing_scheme;
        /* Get hash algorithm from digest size */
        r = ifapi_get_hash_alg_for_size(digest->size, &hash_alg);
        return_if_error2(r, "Invalid digest size.");

        sig_scheme->details.any.hashAlg = hash_alg;
        return TSS2_RC_SUCCESS;
    }
}

/** State machine for changing the hierarchy authorization.
 *
 * First it will be tried to set the auth value of the hierarchy with a
 * "null" authorization. If this trial is not successful it will be tried to
 * authorize the hierarchy via a callback.
 * If an not null auth value is passed with_auth is set to yes for the
 * object otherwise to no. So for later authorizations it will be clear
 * whether null authorization is possible or not.
 *
 * @param[in] context The FAPI_CONTEXT.
 * @param[in] handle The ESAPI handle of the hierarchy.
 * @param[in,out] hierarchy_object The internal FAPI representation of a
 *                hierarchy.
 * @param[in] newAuthValue The new authorization for the hierarchy.
 *
 * @retval TSS2_RC_SUCCESS on success.
 * @retval TSS2_ESYS_RC_* possible error codes of ESAPI.
 * @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_FAPI_RC_AUTHORIZATION_UNKNOWN if a required authorization callback
 *         is not set.
 * @retval TSS2_FAPI_RC_MEMORY if not enough memory can be allocated.
 * @retval TSS2_FAPI_RC_AUTHORIZATION_FAILED if the authorization attempt fails.
 * @retval TSS2_FAPI_RC_GENERAL_FAILURE if an internal error occured.
 * @retval TSS2_FAPI_RC_PATH_NOT_FOUND if a FAPI object path was not found
 *         during authorization.
 * @retval TSS2_FAPI_RC_KEY_NOT_FOUND if a key was not found.
 * @retval TSS2_FAPI_RC_IO_ERROR if an error occured while accessing the
 *         object store.
 * @retval TSS2_FAPI_RC_POLICY_UNKNOWN if policy search for a certain policy digest
 *         was not successful.
 */
TSS2_RC
ifapi_change_auth_hierarchy(
    FAPI_CONTEXT *context,
    ESYS_TR handle,
    IFAPI_OBJECT *hierarchy_object,
    TPM2B_AUTH *newAuthValue)
{
    TSS2_RC r;
    ESYS_TR auth_session;

    switch (context->hierarchy_state) {
    statecase(context->hierarchy_state, HIERARCHY_CHANGE_AUTH_INIT);
        if (hierarchy_object->misc.hierarchy.with_auth == TPM2_YES ||
            policy_digest_size(hierarchy_object)) {
            r = ifapi_authorize_object(context, hierarchy_object, &auth_session);
            FAPI_SYNC(r, "Authorize hierarchy.", error);
        } else {
            auth_session = context->session1;
        }

        r = Esys_HierarchyChangeAuth_Async(context->esys,
                                           handle,
                                           (auth_session
                                            && auth_session != ESYS_TR_NONE) ?
                                           auth_session : ESYS_TR_PASSWORD,
                                           ESYS_TR_NONE, ESYS_TR_NONE,
                                           newAuthValue);
        return_if_error(r, "HierarchyChangeAuth");
        fallthrough;

    statecase(context->hierarchy_state, HIERARCHY_CHANGE_AUTH_NULL_AUTH_SENT);
        r = Esys_HierarchyChangeAuth_Finish(context->esys);
        return_try_again(r);

        if  (number_rc(r) == TPM2_RC_BAD_AUTH &&
             hierarchy_object->misc.hierarchy.with_auth == TPM2_NO) {

            /* Retry after NULL authorization was not successful */
            char *description;
            r = ifapi_get_description(hierarchy_object, &description);
            return_if_error(r, "Get description");

            r = ifapi_set_auth(context, hierarchy_object, description);
            SAFE_FREE(description);
            return_if_error(r, "HierarchyChangeAuth");

            r = Esys_HierarchyChangeAuth_Async(context->esys,
                                               handle,
                                               (context->session1
                                                && context->session1 != ESYS_TR_NONE) ?
                                               context->session1 : ESYS_TR_PASSWORD,
                                               ESYS_TR_NONE, ESYS_TR_NONE,
                                               newAuthValue);
            return_if_error(r, "HierarchyChangeAuth");
            return TSS2_FAPI_RC_TRY_AGAIN;
        }
        return_if_error(r, "HierarchyChangeAuth");

        if (newAuthValue->size > 0)
            hierarchy_object->misc.hierarchy.with_auth = TPM2_YES;
        else
            hierarchy_object->misc.hierarchy.with_auth = TPM2_NO;

        context->hierarchy_state = HIERARCHY_CHANGE_AUTH_INIT;
        return r;

    statecasedefault(context->hierarchy_state);
    }
error:
    return r;
}

/** State machine for changing the policy of a hierarchy.
 *
 * Based on a passed policy the policy digest will be computed.
 * First it will be tried to set the policy of the hierarchy with a
 * "null" authorization. If this trial is not successful it will be tried to
 * authorize the hierarchy via a callback.
 * If an not null auth value is passed with_auth is set to yes for the
 * object otherwise to no. So for later authorizations it will be clear
 * whether null authorization is possible or not.
 *
 * @param[in] context The FAPI_CONTEXT.
 * @param[in] handle The ESAPI handle of the hierarchy.
 * @param[in,out] hierarchy_object The internal FAPI representation of a
 *                hierarchy.
 * @param[in] policy The new policy assigned to the hierarchy.
 *
 * @retval TSS2_RC_SUCCESS on success.
 * @retval TSS2_ESYS_RC_* possible error codes of ESAPI.
 * @retval TSS2_FAPI_RC_MEMORY if not enough memory can be allocated.
 * @retval TSS2_FAPI_RC_GENERAL_FAILURE If an internal error occurs, which is
 *         not covered by other return codes.
 * @retval TSS2_FAPI_RC_BAD_VALUE If wrong values are detected during policy calculation.
 * @retval TSS2_FAPI_RC_IO_ERROR If an error occurs during access to the policy
 *         store.
 * @retval TSS2_FAPI_RC_PATH_NOT_FOUND If an object needed for policy calculation was
 *         not found.
 * @retval TSS2_FAPI_RC_POLICY_UNKNOWN If policy search for a certain policy digest was
 *         not successful.
 * @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_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
 * @retval TSS2_FAPI_RC_KEY_NOT_FOUND if a key was not found.
 * @retval TSS2_FAPI_RC_AUTHORIZATION_UNKNOWN if a required authorization callback
 *         is not set.
 * @retval TSS2_FAPI_RC_AUTHORIZATION_FAILED if the authorization attempt fails.
 * @retval TSS2_FAPI_RC_NOT_PROVISIONED FAPI was not provisioned.
 * @retval TSS2_FAPI_RC_BAD_PATH if the path is used in inappropriate context
 *         or contains illegal characters.
 */
TSS2_RC
ifapi_change_policy_hierarchy(
    FAPI_CONTEXT *context,
    ESYS_TR handle,
    IFAPI_OBJECT *hierarchy_object,
    TPMS_POLICY *policy)
{
    TSS2_RC r;
    ESYS_TR auth_session;

    switch (context->hierarchy_policy_state) {
    statecase(context->hierarchy_policy_state, HIERARCHY_CHANGE_POLICY_INIT);
        if ((! policy || ! policy->policy) && !hierarchy_object->policy) {
            /* No policy will be used for hierarchy */
            return TSS2_RC_SUCCESS;
        }
        fallthrough;

    statecase(context->hierarchy_policy_state, HIERARCHY_CHANGE_POLICY_AUTHORIZE);
        if (hierarchy_object->misc.hierarchy.with_auth == TPM2_YES ||
            policy_digest_size(hierarchy_object)) {
            r = ifapi_authorize_object(context, hierarchy_object, &auth_session);
            FAPI_SYNC(r, "Authorize hierarchy.", error);
        } else {
            auth_session = context->session1;
        }

        if (policy) {
            context->policy.state = POLICY_INIT;

            /* Calculate the policy digest which will be used as hierarchy policy. */
            r = ifapi_calculate_tree(context, NULL, /**< no path needed */
                                     policy,
                                     context->profiles.default_profile.nameAlg,
                                     &context->cmd.Provision.digest_idx,
                                     &context->cmd.Provision.hash_size);
            goto_if_error(r, "Policy calculation", error);

            /* Policy data will be stored in the provisioning context. */
            context->cmd.Provision.policy_digest.size = context->cmd.Provision.hash_size;
            memcpy(&context->cmd.Provision.policy_digest.buffer[0],
                   &policy
                   ->policyDigests.digests[context->cmd.Provision.digest_idx].digest,
                   context->cmd.Provision.hash_size);

            hierarchy_object->policy = policy;
            hierarchy_object->misc.hierarchy.authPolicy = context->cmd.Provision.policy_digest;
        } else {
            /* No policy will be used for this hierarchy. */
            context->cmd.Provision.policy_digest.size = 0;
            ifapi_cleanup_policy(hierarchy_object->policy);
            SAFE_FREE(hierarchy_object->policy);
            hierarchy_object->policy = NULL;
            hierarchy_object->misc.hierarchy.with_auth = TPM2_NO;
            hierarchy_object->misc.hierarchy.authPolicy.size = 0;
        }

        /* Prepare the setting of the policy. */
        r = Esys_SetPrimaryPolicy_Async(context->esys, handle,
                                        (auth_session
                                         && auth_session != ESYS_TR_NONE) ?
                                        auth_session : ESYS_TR_PASSWORD,
                                        ESYS_TR_NONE, ESYS_TR_NONE,
                                        &context->cmd.Provision.policy_digest,
                                        context->cmd.Provision.policy_digest.size ?
                                        context->profiles.default_profile.nameAlg :
                                        TPM2_ALG_NULL);
        return_if_error(r, "Esys_SetPrimaryPolicy_Async");
        fallthrough;

    statecase(context->hierarchy_policy_state, HIERARCHY_CHANGE_POLICY_NULL_AUTH_SENT);
        r = Esys_SetPrimaryPolicy_Finish(context->esys);
        return_try_again(r);
        if (number_rc(r) == TPM2_RC_BAD_AUTH  &&
             hierarchy_object->misc.hierarchy.with_auth == TPM2_NO) {
            /* Retry after NULL authorization was not successful */
            char *description;
            r = ifapi_get_description(hierarchy_object, &description);
            return_if_error(r, "Get description");

            r = ifapi_set_auth(context, hierarchy_object, description);
            SAFE_FREE(description);
            return_if_error(r, "HierarchyChangePolicy");

            r = Esys_SetPrimaryPolicy_Async(context->esys, handle,
                                            (context->session1
                                             && context->session1 != ESYS_TR_NONE) ?
                                            context->session1 : ESYS_TR_PASSWORD,
                                            ESYS_TR_NONE, ESYS_TR_NONE,
                                            &context->cmd.Provision.policy_digest,
                                            context->profiles.default_profile.nameAlg);
            return_if_error(r, "Esys_SetPrimaryPolicy_Async");
            return TSS2_FAPI_RC_TRY_AGAIN;
        }
        return_if_error(r, "Set primary policy");
        break;

    statecasedefault(context->hierarchy_policy_state);
    }

error:
    return r;
}

/** Allocate ifapi object and store the result in a linked list.
 *
 * Allocated ifapi objects will be recorded in the context.
 *
 * @param[in,out] context The FAPI_CONTEXT.
 *
 * @retval The allocated ifapi object.
 * @retval NULL if the object cannot be allocated.
 */
IFAPI_OBJECT
*ifapi_allocate_object(FAPI_CONTEXT *context)
{
    NODE_OBJECT_T *node = calloc(1, sizeof(NODE_OBJECT_T));
    if (!node)
        return NULL;

    node->object = calloc(1, sizeof(IFAPI_OBJECT));
    if (!node->object) {
        free(node);
        return NULL;
    }
    node->next = context->object_list;
    context->object_list = node;
    return (IFAPI_OBJECT *) node->object;
}

/** Free all ifapi objects stored in the context.
 *
 * @param[in,out] context The FAPI_CONTEXT.
 */
void
ifapi_free_objects(FAPI_CONTEXT *context)
{
    NODE_OBJECT_T *free_node;
    NODE_OBJECT_T *node = context->object_list;
    while (node) {
        free(node->object);
        free_node = node;
        node = node->next;
        free(free_node);
    }
}

/** Free ifapi a object stored in the context.
 *
 * @param[in,out] context The FAPI_CONTEXT.
 * @param[in,out] object The object which should be removed from the
 *                the linked list stored in context.
 */
void
ifapi_free_object(FAPI_CONTEXT *context, IFAPI_OBJECT **object)
{
    NODE_OBJECT_T *node;
    NODE_OBJECT_T **update_ptr;

    for (node = context->object_list,
             update_ptr = &context->object_list;
             node != NULL;
         update_ptr = &node->next, node = node->next) {
        if (node->object == object) {
            *update_ptr = node->next;
            SAFE_FREE(node->object);
            SAFE_FREE(node);
            *object = NULL;
            return;
        }
    }
}

#define ADD_CAPABILITY_INFO(capability, field, subfield, max_count, property_count) \
    if (context->cmd.GetInfo.fetched_data->data.capability.count > max_count - property_count) { \
        context->cmd.GetInfo.fetched_data->data.capability.count = max_count - property_count; \
    } \
\
    memmove(&context->cmd.GetInfo.capability_data->data.capability.field[property_count], \
            context->cmd.GetInfo.fetched_data->data.capability.field, \
            context->cmd.GetInfo.fetched_data->data.capability.count \
            * sizeof(context->cmd.GetInfo.fetched_data->data.capability.field[0]));       \
    property_count += context->cmd.GetInfo.fetched_data->data.capability.count; \
\
    context->cmd.GetInfo.capability_data->data.capability.count = property_count; \
\
    if (more_data && property_count < count \
        && context->cmd.GetInfo.fetched_data->data.capability.count) {  \
        context->cmd.GetInfo.property \
            = context->cmd.GetInfo.capability_data->data. \
            capability.field[property_count - 1]subfield + 1;   \
    } else { \
        more_data = false; \
    }


/** Prepare the receiving of capability data.
 *
 * @param[in,out] context The FAPI_CONTEXT.
 *
 * @retval TSS2_RC_SUCCESS.
 */
TPM2_RC
ifapi_capability_init(FAPI_CONTEXT *context)
{
    context->cmd.GetInfo.capability_data = NULL;
    context->cmd.GetInfo.fetched_data = NULL;

    return TSS2_RC_SUCCESS;


}

/** State machine for receiving TPM capability information.
 *
 * The state machine shares the state with the FAPI function Fapi_GetInfo.
 * context->state == GET_INFO_GET_CAP_MORE signals that more capability data can
 * be retrieved.
 *
 * @param[in,out] context The FAPI_CONTEXT.
 * @param[in]     capability The capability to be retrieved.
 * @param[in]     count The maximal number of items that should be retrieved.
 * @param[out]    capability_data The retrieved capability information.
 *
 * @retval TSS2_RC_SUCCESS If all capability data is retrieved.
 * @retval TSS2_FAPI_RC_TRY_AGAIN if more capability data is available.
 * @retval TSS2_ESYS_RC_* possible error codes of ESAPI.
 * @retval TSS2_FAPI_RC_GENERAL_FAILURE if an internal error occurred.
 * @retval TSS2_FAPI_RC_BAD_VALUE if an invalid value was passed into
 *         the function.
 * @retval TSS2_FAPI_RC_BAD_SEQUENCE if the context has an asynchronous
 *         operation already pending.
 */
TPM2_RC
ifapi_capability_get(FAPI_CONTEXT *context, TPM2_CAP capability,
                     UINT32 count, TPMS_CAPABILITY_DATA **capability_data) {

    TPMI_YES_NO more_data;
    TSS2_RC r = TSS2_RC_SUCCESS;
    ESYS_CONTEXT *ectx = context->esys;

    switch (context->state) {
    statecase(context->state, GET_INFO_GET_CAP);
        /* fetch capability info */
        context->cmd.GetInfo.fetched_data = NULL;
        context->cmd.GetInfo.capability_data = NULL;
        fallthrough;

    statecase(context->state, GET_INFO_GET_CAP_MORE);
        r = Esys_GetCapability_Async(ectx, ESYS_TR_NONE, ESYS_TR_NONE, ESYS_TR_NONE,
                                     capability, context->cmd.GetInfo.property,
                                     count - context->cmd.GetInfo.property_count);
        goto_if_error(r, "Error GetCapability", error_cleanup);
        fallthrough;

    statecase(context->state, GET_INFO_WAIT_FOR_CAP);
        r = Esys_GetCapability_Finish(ectx, &more_data, &context->cmd.GetInfo.fetched_data);
        return_try_again(r);
        goto_if_error(r, "Error GetCapability", error_cleanup);

        LOG_TRACE("GetCapability: capability: 0x%x, property: 0x%x", capability,
                  context->cmd.GetInfo.property);

        if (context->cmd.GetInfo.fetched_data->capability != capability) {
            goto_error(r, TSS2_FAPI_RC_GENERAL_FAILURE,
                       "TPM returned different capability than requested: 0x%x != 0x%x",
                       error_cleanup,
                       context->cmd.GetInfo.fetched_data->capability, capability);
        }

        if (context->cmd.GetInfo.capability_data == NULL) {
            /* reuse the TPM's result structure */
            context->cmd.GetInfo.capability_data = context->cmd.GetInfo.fetched_data;

            if (!more_data) {
                /* there won't be another iteration of the loop, just return the result unmodified */
                *capability_data = context->cmd.GetInfo.capability_data;
                return TPM2_RC_SUCCESS;
            }
        }

        /* append the TPM's results to the initial structure, as long as there is still space left */
        switch (capability) {
        case TPM2_CAP_ALGS:
            ADD_CAPABILITY_INFO(algorithms, algProperties, .alg,
                                TPM2_MAX_CAP_ALGS,
                                context->cmd.GetInfo.property_count);
            break;
        case TPM2_CAP_HANDLES:
            ADD_CAPABILITY_INFO(handles, handle,,
                                TPM2_MAX_CAP_HANDLES,
                                context->cmd.GetInfo.property_count);
            break;
        case TPM2_CAP_COMMANDS:
            ADD_CAPABILITY_INFO(command, commandAttributes,,
                                TPM2_MAX_CAP_CC,
                                context->cmd.GetInfo.property_count);
            /* workaround because tpm2-tss does not implement attribute commandIndex for TPMA_CC */
            context->cmd.GetInfo.property &= TPMA_CC_COMMANDINDEX_MASK;
            break;
        case TPM2_CAP_PP_COMMANDS:
            ADD_CAPABILITY_INFO(ppCommands, commandCodes,,
                                TPM2_MAX_CAP_CC,
                                context->cmd.GetInfo.property_count);
            break;
        case TPM2_CAP_AUDIT_COMMANDS:
            ADD_CAPABILITY_INFO(auditCommands, commandCodes,,
                                TPM2_MAX_CAP_CC,
                                context->cmd.GetInfo.property_count);
            break;
        case TPM2_CAP_PCRS:
            ADD_CAPABILITY_INFO(assignedPCR, pcrSelections, .hash,
                                TPM2_NUM_PCR_BANKS,
                                context->cmd.GetInfo.property_count);
            break;
        case TPM2_CAP_TPM_PROPERTIES:
            ADD_CAPABILITY_INFO(tpmProperties, tpmProperty, .property,
                                TPM2_MAX_TPM_PROPERTIES,
                                context->cmd.GetInfo.property_count);
            break;
        case TPM2_CAP_PCR_PROPERTIES:
            ADD_CAPABILITY_INFO(pcrProperties, pcrProperty, .tag,
                                TPM2_MAX_PCR_PROPERTIES,
                                context->cmd.GetInfo.property_count);
            break;
        case TPM2_CAP_ECC_CURVES:
            ADD_CAPABILITY_INFO(eccCurves, eccCurves,,
                                TPM2_MAX_ECC_CURVES,
                                context->cmd.GetInfo.property_count);
            break;
        case TPM2_CAP_VENDOR_PROPERTY:
            ADD_CAPABILITY_INFO(intelPttProperty, property,,
                                TPM2_MAX_PTT_PROPERTIES,
                                context->cmd.GetInfo.property_count);
            break;
        default:
            LOG_ERROR("Unsupported capability: 0x%x\n", capability);
            if (context->cmd.GetInfo.fetched_data != context->cmd.GetInfo.capability_data) {
                free(context->cmd.GetInfo.fetched_data);
            }
            free(context->cmd.GetInfo.capability_data);
            *capability_data = NULL;
            return TSS2_FAPI_RC_BAD_VALUE;
        }

        if (context->cmd.GetInfo.fetched_data != context->cmd.GetInfo.capability_data) {
            free(context->cmd.GetInfo.fetched_data);
        }
        *capability_data = context->cmd.GetInfo.capability_data;
        break;

    statecasedefault(context->state);
    }
    if (more_data) {
        context->state = GET_INFO_GET_CAP_MORE;
        return TSS2_FAPI_RC_TRY_AGAIN;
    } else {
        context->state = _FAPI_STATE_INIT;
        return TSS2_RC_SUCCESS;
    }

error_cleanup:
    context->state = _FAPI_STATE_INIT;
    SAFE_FREE(context->cmd.GetInfo.capability_data);
    SAFE_FREE(context->cmd.GetInfo.fetched_data);
    return r;
}

/** Get certificates stored in NV ram.
 *
 * The NV handles in the certificate range are determined. The corresponding
 * certificates are read out and stored in a linked list.
 *
 * @param[in,out] context The FAPI_CONTEXT. The sub context for NV reading
 *                will be used.
 * @param[in] min_handle The first possible handle in the handle range.
 * @param[in] max_handle Maximal handle to filter out the handles not in the
 *            handle range for certificates.
 * @param[out] cert_list The callee allocates linked list of certificates.
 *
 * @retval TSS2_RC_SUCCESS on success.
 * @retval TSS2_ESYS_RC_* possible error codes of ESAPI.
 * @retval TSS2_FAPI_RC_MEMORY if not enough memory can be allocated.
 *
 * @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_FAPI_RC_AUTHORIZATION_UNKNOWN if a required authorization callback
 *         is not set.
 * @retval TSS2_FAPI_RC_AUTHORIZATION_FAILED if the authorization attempt fails.
 * @retval TSS2_FAPI_RC_GENERAL_FAILURE if an internal error occurred.
 * @retval TSS2_FAPI_RC_IO_ERROR if an error occurred while accessing the
 *         object store.
 * @retval TSS2_FAPI_RC_POLICY_UNKNOWN if policy search for a certain policy digest
 *         was not successful.
 * @retval TSS2_FAPI_RC_NOT_PROVISIONED FAPI was not provisioned.
 * @retval TSS2_FAPI_RC_KEY_NOT_FOUND if a key was not found.
 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
 * @retval TSS2_FAPI_RC_BAD_PATH if the path is used in inappropriate context
 *         or contains illegal characters.
 * @retval TSS2_FAPI_RC_BAD_VALUE if an invalid value was passed into
 *         the function.
 * @retval TSS2_FAPI_RC_PATH_NOT_FOUND if a FAPI object path was not found
 *         during authorization.
 */
TSS2_RC
ifapi_get_certificates(
    FAPI_CONTEXT *context,
    UINT32 min_handle,
    UINT32 max_handle,
    NODE_OBJECT_T **cert_list)
{
    TSS2_RC r;
    TPMI_YES_NO moreData;
    uint8_t *cert_data;
    size_t cert_size;

    context->cmd.Provision.cert_nv_idx = MIN_EK_CERT_HANDLE;

    switch (context->get_cert_state) {
    statecase(context->get_cert_state, GET_CERT_INIT);
        *cert_list = NULL;
        context->cmd.Provision.capabilityData = NULL;
        context->cmd.Provision.cert_idx = 0;
        /* Prepare the reading of the capability handles in the certificate range */
        r = Esys_GetCapability_Async(context->esys,
                                     ESYS_TR_NONE, ESYS_TR_NONE, ESYS_TR_NONE,
                                     TPM2_CAP_HANDLES, min_handle,
                                     TPM2_MAX_CAP_HANDLES);
        goto_if_error(r, "Esys_GetCapability_Async", error);
        fallthrough;

    statecase(context->get_cert_state, GET_CERT_WAIT_FOR_GET_CAP);
        r = Esys_GetCapability_Finish(context->esys, &moreData,
                                      &context->cmd.Provision.capabilityData);
        try_again_or_error(r, "GetCapablity_Finish");

        if (!context->cmd.Provision.capabilityData ||
            context->cmd.Provision.capabilityData->data.handles.count == 0) {
            *cert_list = NULL;
            SAFE_FREE(context->cmd.Provision.capabilityData);
            return TSS2_RC_SUCCESS;
        }
        context->cmd.Provision.cert_count =
            context->cmd.Provision.capabilityData->data.handles.count;

        /* Filter out NV handles beyond the EK cert range */
        for (size_t i = 0; i < context->cmd.Provision.cert_count; i++) {
            if (context->cmd.Provision.capabilityData->data.handles.handle[i] > max_handle) {
                context->cmd.Provision.cert_count = i;
                break;
            }
        }
        fallthrough;

    statecase(context->get_cert_state, GET_CERT_GET_CERT_NV);
        goto_if_null(context->cmd.Provision.capabilityData,
            "capabilityData is null", TSS2_FAPI_RC_MEMORY, error);
        context->cmd.Provision.cert_nv_idx
            = context->cmd.Provision.capabilityData
            ->data.handles.handle[context->cmd.Provision.cert_idx];

        ifapi_init_hierarchy_object(&context->nv_cmd.auth_object,
                                    TPM2_RH_OWNER);

        r = Esys_TR_FromTPMPublic_Async(context->esys,
                                        context->cmd.Provision.cert_nv_idx,
                                        ESYS_TR_NONE, ESYS_TR_NONE, ESYS_TR_NONE);
        goto_if_error_reset_state(r, "Esys_TR_FromTPMPublic_Async", error);
        fallthrough;

    statecase(context->get_cert_state, GET_CERT_GET_CERT_NV_FINISH);
        r = Esys_TR_FromTPMPublic_Finish(context->esys,
                                         &context->cmd.Provision.esys_nv_cert_handle);
        try_again_or_error_goto(r, "TR_FromTPMPublic_Finish", error);

        /* Read public to get size of certificate */
        r = Esys_NV_ReadPublic_Async(context->esys,
                                     context->cmd.Provision.esys_nv_cert_handle,
                                     ESYS_TR_NONE, ESYS_TR_NONE, ESYS_TR_NONE);
        goto_if_error_reset_state(r, "Esys_NV_ReadPublic_Async", error);
        fallthrough;

    statecase(context->get_cert_state, GET_CERT_GET_CERT_READ_PUBLIC);
        r = Esys_NV_ReadPublic_Finish(context->esys,
                                      &context->cmd.Provision.nvPublic,
                                      NULL);
        try_again_or_error_goto(r, "Error: nv read public", error);

        /* TPMA_NV_NO_DA is set for NV certificate */
        context->nv_cmd.nv_object.misc.nv.public.nvPublic.attributes = TPMA_NV_NO_DA;

        r = ifapi_keystore_load_async(&context->keystore, &context->io, "/HS");
        goto_if_error_reset_state(r, "Could not open hierarchy /HS", error);

        fallthrough;

    statecase(context->get_cert_state, GET_CERT_GET_CERT_READ_HIERARCHY);
        r = ifapi_keystore_load_finish(&context->keystore, &context->io,
                                       &context->nv_cmd.auth_object);
        try_again_or_error_goto(r, "read_finish failed", error);

        /* Prepare context for nv read */
        r = ifapi_initialize_object(context->esys, &context->nv_cmd.auth_object);
        goto_if_error_reset_state(r, "Initialize hierarchy object", error);

        context->nv_cmd.auth_object.handle = ESYS_TR_RH_OWNER;
        context->nv_cmd.data_idx = 0;
        context->nv_cmd.auth_index = ESYS_TR_RH_OWNER;
        context->nv_cmd.numBytes = context->cmd.Provision.nvPublic->nvPublic.dataSize;
        context->nv_cmd.esys_handle = context->cmd.Provision.esys_nv_cert_handle;
        context->nv_cmd.offset = 0;
        context->cmd.Provision.pem_cert = NULL;
        context->session1 = ESYS_TR_PASSWORD;
        context->session2 = ESYS_TR_NONE;
        context->nv_cmd.nv_read_state = NV_READ_INIT;
        memset(&context->nv_cmd.nv_object, 0, sizeof(IFAPI_OBJECT));
        SAFE_FREE(context->cmd.Provision.nvPublic);
        fallthrough;

    statecase(context->get_cert_state, GET_CERT_READ_CERT);
        r = ifapi_nv_read(context, &cert_data, &cert_size);
        try_again_or_error_goto(r, " FAPI NV_Read", error);

        context->cmd.Provision.cert_idx += 1;

        /* Add cert to list */
        if (context->cmd.Provision.cert_idx == context->cmd.Provision.cert_count) {
            context->get_cert_state = GET_CERT_GET_CERT_NV;

            r = push_object_with_size_to_list(cert_data, cert_size, cert_list);
            goto_if_error(r, "Store certificate in list.", error);

            ifapi_cleanup_ifapi_object(&context->nv_cmd.auth_object);

            SAFE_FREE(context->cmd.Provision.capabilityData);
            return TSS2_RC_SUCCESS;
        } else {
            context->get_cert_state = GET_CERT_GET_CERT_NV;
            return TSS2_FAPI_RC_TRY_AGAIN;
        }
        break;

    statecasedefault(context->get_cert_state);
    }

error:
    SAFE_FREE(context->cmd.Provision.nvPublic);
    SAFE_FREE(context->cmd.Provision.capabilityData);
    ifapi_cleanup_ifapi_object(&context->nv_cmd.auth_object);
    ifapi_free_object_list(*cert_list);
    return r;
}


/** Get description of an internal FAPI object.
 *
 * @param[in] object The object with the description.
 * @param[out] description The callee allocated description.
 *
 * @retval TSS2_RC_SUCCESS If a copy of the description can be returned
 *         or if no description exists.
 * @retval TSS2_FAPI_RC_MEMORY in the copy cannot be allocated.
 */
TSS2_RC
ifapi_get_description(IFAPI_OBJECT *object, char **description)
{
    char *obj_description = NULL;

    switch (object->objectType) {
    case IFAPI_KEY_OBJ:
        obj_description = object->misc.key.description;
        break;
    case IFAPI_NV_OBJ:
        obj_description = object->misc.nv.description;
        break;
    case IFAPI_HIERARCHY_OBJ:
        if (object->misc.hierarchy.description)
            obj_description = object->misc.hierarchy.description;
        else if (object->handle == ESYS_TR_RH_OWNER)
            obj_description = "Owner Hierarchy";
        else if (object->handle == ESYS_TR_RH_ENDORSEMENT)
            obj_description = "Endorsement Hierarchy";
        else if (object->handle == ESYS_TR_RH_LOCKOUT)
            obj_description = "Lockout Hierarchy";
        else if (object->handle == ESYS_TR_RH_NULL)
            obj_description = "Null Hierarchy";
        else
            obj_description = "Hierarchy";
        break;
    default:
        *description = NULL;
        return TSS2_RC_SUCCESS;
    }
    if (obj_description) {
        *description = strdup(obj_description);
        check_oom(*description);
    } else {
        *description = NULL;
    }
    return TSS2_RC_SUCCESS;
}

/** Set description of an internal FAPI object.
 *
 * @param[in,out] object The object with the description.
 * @param[in] description The description char strint or NULL.
 */
void
ifapi_set_description(IFAPI_OBJECT *object, char *description)
{
    switch (object->objectType) {
    case IFAPI_KEY_OBJ:
        SAFE_FREE(object->misc.key.description);
        object->misc.key.description = description;
        break;
    case IFAPI_NV_OBJ:
        SAFE_FREE(object->misc.nv.description);
        object->misc.nv.description = description;
        break;
    case IFAPI_HIERARCHY_OBJ:
        SAFE_FREE(object->misc.hierarchy.description);
        object->misc.hierarchy.description = description;
        break;
    default:
        LOG_WARNING("Description can't be set");
        break;
    }
}

/** Determine key properties (primary, null hierarchy).
 *
 * It will be checked whether a path is the path of a primary key,
 * and whether it's a key in null hiearchy
 *
 * @param[in,out] context The FAPI_CONTEXT.
 * @param[in]     key_path the key path.
 * @param[out]    is_primary if key path is the path of a primary.
 * @param[out]    in_null_hierarchy if key is a null hierarchy key.
 *
 * @retval TSS2_RC_SUCCESS If the preparation is successful.
 * @retval TSS2_FAPI_RC_MEMORY if memory could not be allocated for path names.
 * @retval TSS2_FAPI_RC_BAD_VALUE if an invalid value was passed into
 *         the function.
 * @retval TSS2_FAPI_RC_BAD_PATH if the path is used in inappropriate context
 *         or contains illegal characters.
 * @retval TSS2_FAPI_RC_PATH_NOT_FOUND if a FAPI object path was not found
 *         during authorization.
 */
TSS2_RC
ifapi_get_key_properties(
    FAPI_CONTEXT *context,
    char const *key_path,
    bool *is_primary,
    bool *in_null_hierarchy)
{
    TSS2_RC r;
    NODE_STR_T *path_list = NULL;
    size_t path_length;
    const char *hierarchy;

    LOG_TRACE("Check primary: %s", key_path);

    *is_primary = false;
    *in_null_hierarchy = false;

    r = get_explicit_key_path(&context->keystore, key_path, &path_list);
    return_if_error(r, "Compute explicit path.");

    path_length = ifapi_path_length(path_list);

    if (path_length == 3) {
        if (strncmp("P_", path_list->str, 2) == 0) {
            hierarchy = path_list->next->str;
            if (strcmp(hierarchy,"HS") == 0 ||
                strcmp(hierarchy,"HE") == 0 ||
                strcmp(hierarchy,"HN") == 0) {
                *is_primary = true;
            }
        }
    }
    if (path_length >= 3) {
        hierarchy = path_list->next->str;
        if (strcmp(hierarchy,"HN") == 0)
            *in_null_hierarchy = true;
    }
    free_string_list(path_list);
    return TSS2_RC_SUCCESS;
}

/** Creation of a primary key.
 *
 * Depending on the flags stored in the context the creation of a primary
 * key will be prepared.
 *
 * @param[in] context The FAPI_CONTEXT.
 * @param[in] template The template which defines the key attributes and whether the
 *            key will be persistent.
 * @retval TSS2_RC_SUCCESS on success.
 * @retval TSS2_FAPI_RC_BAD_VALUE if a wrong type was passed.
 * @retval TSS2_ESYS_RC_* possible error codes of ESAPI.
 * @retval TSS2_FAPI_RC_MEMORY if not enough memory can be allocated.
 * @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
 * @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_FAPI_RC_IO_ERROR if an error occurred while accessing the
 *         object store.
 * @retval TSS2_FAPI_RC_GENERAL_FAILURE if an internal error occurred.
 * @retval TSS2_FAPI_RC_PATH_NOT_FOUND if a FAPI object path was not found
 *         during authorization.
 * @retval TSS2_FAPI_RC_KEY_NOT_FOUND if a key was not found.
 * @retval TSS2_FAPI_RC_NOT_PROVISIONED FAPI was not provisioned.
 * @retval TSS2_FAPI_RC_BAD_PATH if the path is used in inappropriate context
 *         or contains illegal characters.
 * @retval TSS2_FAPI_RC_AUTHORIZATION_UNKNOWN if a required authorization callback
 *         is not set.
 * @retval TSS2_FAPI_RC_AUTHORIZATION_FAILED if the authorization attempt fails.
 * @retval TSS2_FAPI_RC_POLICY_UNKNOWN if policy search for a certain policy digest
 *         was not successful.
 * @retval TSS2_FAPI_RC_PATH_ALREADY_EXISTS if the object already exists in object store.
 */
TSS2_RC
ifapi_create_primary(
    FAPI_CONTEXT *context,
    IFAPI_KEY_TEMPLATE *template)
{
    TSS2_RC r;
    ESYS_TR auth_session;
    TPM2B_PUBLIC *outPublic = NULL;
    TPM2B_CREATION_DATA *creationData = NULL;
    TPM2B_DIGEST *creationHash = NULL;
    TPMT_TK_CREATION *creationTicket = NULL;
    IFAPI_OBJECT *object = &context->cmd.Key_Create.object;
    IFAPI_OBJECT *hierarchy = &context->cmd.Key_Create.hierarchy;
    IFAPI_KEY *pkey = &context->cmd.Key_Create.object.misc.key;
    const char *hierarchy_path;
    const char *profile_name;

    /* Compute policy */

    switch (context->cmd.Key_Create.state) {
    statecase(context->cmd.Key_Create.state, KEY_CREATE_PRIMARY_INIT);
        profile_name = context->loadKey.path_list->str;
        r = ifapi_profiles_get(&context->profiles, profile_name,
                               &context->cmd.Key_Create.profile);
        goto_if_error_reset_state(r, "Retrieving profile data", error_cleanup);

        context->cmd.Key_Create.public_templ = *template;
        r = ifapi_merge_profile_into_template(context->cmd.Key_Create.profile,
                                              &context->cmd.Key_Create.public_templ);
        goto_if_error_reset_state(r, "Merge profile", error_cleanup);

        /* Persistent keys are not allowd in the NULL hierarchy. */

        if (template->persistent_handle) {
            hierarchy_path = context->loadKey.path_list->next->str;
            if (strcmp(hierarchy_path, "HN") == 0)
                goto_error_reset_state(r, TSS2_FAPI_RC_BAD_VALUE,
                                       "Persistent keys are not possible in the NULL "
                                       "hierarchy.", error_cleanup);
        }

        if (context->cmd.Key_Create.policyPath
            && strcmp(context->cmd.Key_Create.policyPath, "") != 0)
            context->cmd.Key_Create.state = KEY_CREATE_PRIMARY_CALCULATE_POLICY;
        /* else jump over to KEY_CREATE_PRIMARY_WAIT_FOR_SESSION below */
    /* FALLTHRU */
    case KEY_CREATE_PRIMARY_CALCULATE_POLICY:
        if (context->cmd.Key_Create.state == KEY_CREATE_PRIMARY_CALCULATE_POLICY) {
            r = ifapi_calculate_tree(context, context->cmd.Key_Create.policyPath,
                                     &context->policy.policy,
                                     context->cmd.Key_Create.public_templ.public.publicArea.nameAlg,
                                     &context->policy.digest_idx,
                                     &context->policy.hash_size);
            return_try_again(r);
            goto_if_error2(r, "Calculate policy tree %s", error_cleanup,
                           context->cmd.Key_Create.policyPath);

            /* Store the calculated policy in the key object */
            object->policy = calloc(1, sizeof(TPMS_POLICY));
            return_if_null(object->policy, "Out of memory",
                    TSS2_FAPI_RC_MEMORY);
            *(object->policy) = context->policy.policy;

            context->cmd.Key_Create.public_templ.public.publicArea.authPolicy.size =
                context->policy.hash_size;
            memcpy(&context->cmd.Key_Create.public_templ.public.publicArea.authPolicy.buffer[0],
                   &context->policy.policy.policyDigests.digests[context->policy.digest_idx].digest,
                   context->policy.hash_size);
        }

        r = ifapi_get_sessions_async(context,
                                     IFAPI_SESSION_GENEK | IFAPI_SESSION1,
                                     TPMA_SESSION_ENCRYPT | TPMA_SESSION_DECRYPT, 0);
        goto_if_error_reset_state(r, "Create sessions", error_cleanup);

        fallthrough;

    statecase(context->cmd.Key_Create.state, KEY_CREATE_PRIMARY_WAIT_FOR_SESSION);
        r = ifapi_get_sessions_finish(context, &context->profiles.default_profile,
                                      context->profiles.default_profile.nameAlg);
        return_try_again(r);
        goto_if_error(r, "Create FAPI session.", error_cleanup);

        hierarchy_path = context->loadKey.path_list->next->str;

        r = ifapi_keystore_load_async(&context->keystore, &context->io, hierarchy_path);
        free_string_list(context->loadKey.path_list);
        context->loadKey.path_list = NULL;
        return_if_error2(r, "Could not open hierarchy /%s", hierarchy_path);

        fallthrough;

    statecase(context->cmd.Key_Create.state, KEY_CREATE_PRIMARY_WAIT_FOR_HIERARCHY);
        r = ifapi_keystore_load_finish(&context->keystore, &context->io, hierarchy);
        return_try_again(r);
        return_if_error(r, "read_finish failed");

        r = ifapi_initialize_object(context->esys, hierarchy);
        goto_if_error_reset_state(r, "Initialize hierarchy object", error_cleanup);

        fallthrough;

    statecase(context->cmd.Key_Create.state, KEY_CREATE_PRIMARY_WAIT_FOR_AUTHORIZE1);
        r = ifapi_authorize_object(context, hierarchy, &auth_session);
        FAPI_SYNC(r, "Authorize hierarchy.", error_cleanup);

        r = Esys_CreatePrimary_Async(context->esys, hierarchy->handle,
                                     auth_session,
                                     ESYS_TR_NONE, ESYS_TR_NONE,
                                     &context->cmd.Key_Create.inSensitive,
                                     &context->cmd.Key_Create.public_templ.public,
                                     &context->cmd.Key_Create.outsideInfo,
                                     &context->cmd.Key_Create.creationPCR);
        goto_if_error_reset_state(r, "Prepare create primary", error_cleanup);

        fallthrough;

    statecase(context->cmd.Key_Create.state, KEY_CREATE_PRIMARY_WAIT_FOR_PRIMARY);
        r = Esys_CreatePrimary_Finish(context->esys,
                                      &context->cmd.Key_Create.handle,
                                      &outPublic, &creationData, &creationHash,
                                      &creationTicket);
        try_again_or_error_goto(r, "Create primary.", error_cleanup);

        /* Prepare object for serialization */
        object->system = context->cmd.Key_Create.public_templ.system;
        object->objectType = IFAPI_KEY_OBJ;
        object->misc.key.public = *outPublic;
        object->misc.key.private.size = 0;
        object->misc.key.private.buffer = NULL;
        object->misc.key.policyInstance = NULL;
        object->misc.key.creationData = *creationData;
        object->misc.key.creationTicket = *creationTicket;
        object->misc.key.description = NULL;
        object->misc.key.certificate = NULL;
        object->misc.key.reset_count = context->init_time.clockInfo.resetCount;
        SAFE_FREE(pkey->serialization.buffer);
        r = Esys_TR_Serialize(context->esys, context->cmd.Key_Create.handle,
                              &pkey->serialization.buffer, &pkey->serialization.size);
        goto_if_error(r, "Error serialize esys object", error_cleanup);
        SAFE_FREE(creationData);
        SAFE_FREE(creationTicket);
        SAFE_FREE(creationHash);
        if (context->cmd.Key_Create.inSensitive.sensitive.userAuth.size > 0)
            object->misc.key.with_auth = TPM2_YES;
        else
            object->misc.key.with_auth = TPM2_NO;;
        r = ifapi_get_name(&outPublic->publicArea, &object->misc.key.name);
        goto_if_error(r, "Get key name", error_cleanup);

        if (object->misc.key.public.publicArea.type == TPM2_ALG_RSA)
            object->misc.key.signing_scheme = context->cmd.Key_Create.profile->rsa_signing_scheme;
        else
            object->misc.key.signing_scheme = context->cmd.Key_Create.profile->ecc_signing_scheme;
        fallthrough;

    statecase(context->cmd.Key_Create.state, KEY_CREATE_PRIMARY_WAIT_FOR_AUTHORIZE2);
        if (template->persistent_handle) {
            r = ifapi_authorize_object(context, hierarchy, &auth_session);
            FAPI_SYNC(r, "Authorize hierarchy.", error_cleanup);

            /* Prepare making the created primary permanent. */
            r = Esys_EvictControl_Async(context->esys, hierarchy->handle,
                                        context->cmd.Key_Create.handle,
                                        auth_session, ESYS_TR_NONE,
                                        ESYS_TR_NONE,
                                        object->misc.key.persistent_handle);
            goto_if_error(r, "Error Esys EvictControl", error_cleanup);
        }
        fallthrough;

    statecase(context->cmd.Key_Create.state, KEY_CREATE_PRIMARY_WAIT_FOR_EVICT_CONTROL);
        if (template->persistent_handle) {
            /* Prepare making the loaded key permanent. */
            r = Esys_EvictControl_Finish(context->esys, &object->handle);
            return_try_again(r);
            goto_if_error(r, "Evict control failed", error_cleanup);
        }

        fallthrough;

    statecase(context->cmd.Key_Create.state, KEY_CREATE_PRIMARY_FLUSH);
        /* Flush the primary key. */
        r = ifapi_flush_object(context, context->cmd.Key_Create.handle);
        return_try_again(r);
        goto_if_error(r, "Flush key", error_cleanup);

        fallthrough;

    statecase(context->cmd.Key_Create.state, KEY_CREATE_PRIMARY_WRITE_PREPARE);
        SAFE_FREE(outPublic);

        /* Perform esys serialization */
        r = ifapi_esys_serialize_object(context->esys, object);
        goto_if_error(r, "Prepare serialization", error_cleanup);

        /* Check whether object already exists in key store.*/
        r = ifapi_keystore_object_does_not_exist(&context->keystore,
                                                 context->cmd.Key_Create.keyPath,
                                                 object);
        goto_if_error_reset_state(r, "Could not write: %s", error_cleanup,
                                  context->cmd.Key_Create.keyPath);

        /* Start writing the object to the key store */
        r = ifapi_keystore_store_async(&context->keystore, &context->io,
                                       context->cmd.Key_Create.keyPath, object);
        goto_if_error_reset_state(r, "Could not open: %s", error_cleanup,
                                  context->cmd.Key_Create.keyPath);
        ifapi_cleanup_ifapi_object(object);
        fallthrough;

    statecase(context->cmd.Key_Create.state, KEY_CREATE_PRIMARY_WRITE);
        /* Finish writing the key to the key store */
        r = ifapi_keystore_store_finish(&context->keystore, &context->io);
        return_try_again(r);
        return_if_error_reset_state(r, "write_finish failed");

        fallthrough;

    statecase(context->cmd.Key_Create.state, KEY_CREATE_PRIMARY_CLEANUP);
        r = ifapi_cleanup_session(context);
        try_again_or_error_goto(r, "Cleanup", error_cleanup);

        context->cmd.Key_Create.state = KEY_CREATE_INIT;
        break;

    statecasedefault(context->cmd.Key_Create.state);
    }
    free_string_list(context->loadKey.path_list);
    ifapi_cleanup_ifapi_object(hierarchy);
    SAFE_FREE(outPublic);
    SAFE_FREE(creationData);
    SAFE_FREE(creationHash);
    SAFE_FREE(creationTicket);
    SAFE_FREE(context->cmd.Key_Create.policyPath);
    SAFE_FREE(context->cmd.Key_Create.keyPath);
    ifapi_cleanup_ifapi_object(object);
    ifapi_session_clean(context);
    return TSS2_RC_SUCCESS;

 error_cleanup:
    SAFE_FREE(outPublic);
    SAFE_FREE(creationData);
    SAFE_FREE(creationHash);
    SAFE_FREE(creationTicket);
    SAFE_FREE(context->cmd.Key_Create.policyPath);
    SAFE_FREE(context->cmd.Key_Create.keyPath);
    free_string_list(context->loadKey.path_list);
    ifapi_cleanup_ifapi_object(hierarchy);
    return r;

}
