ESAPI: Rework of internal state engine

This commit reworks the internal state engine of
the ESAPI implementation.
First, a TPM error response is now considered recoverable
and sends the ESAPI back into the initial state.
Second, there is now an extra internal error state, which
is set if there are errors in the internal libraries of
ESAPI that do not rely on extern (application or TPM)
inputs.

Signed-off-by: Andreas Fuchs <andreas.fuchs@sit.fraunhofer.de>
diff --git a/src/tss2-esys/api/Esys_ActivateCredential.c b/src/tss2-esys/api/Esys_ActivateCredential.c
index 200106e..13a50fd 100644
--- a/src/tss2-esys/api/Esys_ActivateCredential.c
+++ b/src/tss2-esys/api/Esys_ActivateCredential.c
@@ -175,6 +175,7 @@
     RSRC_NODE_T *activateHandleNode;
     RSRC_NODE_T *keyHandleNode;
 
+    /* Check context, sequence correctness and set state to error for now */
     if (esysContext == NULL) {
         LOG_ERROR("esyscontext is NULL.");
         return TSS2_ESYS_RC_BAD_REFERENCE;
@@ -182,46 +183,48 @@
     r = iesys_check_sequence_async(esysContext);
     if (r != TSS2_RC_SUCCESS)
         return r;
-    r = check_session_feasability(shandle1, shandle2, shandle3, 1);
-    return_if_error(r, "Check session usage");
+    esysContext->state = _ESYS_STATE_INTERNALERROR;
 
+    /* Check and store input parameters */
+    r = check_session_feasability(shandle1, shandle2, shandle3, 1);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Check session usage");
     store_input_parameters(esysContext, activateHandle, keyHandle,
                 credentialBlob,
                 secret);
+
+    /* Retrieve the metadata objects for provided handles */
     r = esys_GetResourceObject(esysContext, activateHandle, &activateHandleNode);
-    if (r != TPM2_RC_SUCCESS)
-        return r;
+    return_state_if_error(r, _ESYS_STATE_INIT, "activateHandle unknown.");
     r = esys_GetResourceObject(esysContext, keyHandle, &keyHandleNode);
-    if (r != TPM2_RC_SUCCESS)
-        return r;
+    return_state_if_error(r, _ESYS_STATE_INIT, "keyHandle unknown.");
+
+    /* Initial invocation of SAPI to prepare the command buffer with parameters */
     r = Tss2_Sys_ActivateCredential_Prepare(esysContext->sys,
                 (activateHandleNode == NULL) ? TPM2_RH_NULL : activateHandleNode->rsrc.handle,
                 (keyHandleNode == NULL) ? TPM2_RH_NULL : keyHandleNode->rsrc.handle,
                 credentialBlob,
                 secret);
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error async ActivateCredential");
-        return r;
-    }
-    r = init_session_tab(esysContext, shandle1, shandle2, shandle3);
-    return_if_error(r, "Initialize session resources");
+    return_state_if_error(r, _ESYS_STATE_INIT, "SAPI Prepare returned error.");
 
+    /* Calculate the cpHash Values */
+    r = init_session_tab(esysContext, shandle1, shandle2, shandle3);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Initialize session resources");
     iesys_compute_session_value(esysContext->session_tab[0],
                 &activateHandleNode->rsrc.name, &activateHandleNode->auth);
     iesys_compute_session_value(esysContext->session_tab[1],
                 &keyHandleNode->rsrc.name, &keyHandleNode->auth);
     iesys_compute_session_value(esysContext->session_tab[2], NULL, NULL);
-    r = iesys_gen_auths(esysContext, activateHandleNode, keyHandleNode, NULL, &auths);
-    return_if_error(r, "Error in computation of auth values");
 
+    /* Generate the auth values and set them in the SAPI command buffer */
+    r = iesys_gen_auths(esysContext, activateHandleNode, keyHandleNode, NULL, &auths);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Error in computation of auth values");
     esysContext->authsCount = auths.count;
     r = Tss2_Sys_SetCmdAuths(esysContext->sys, &auths);
-    if (r != TSS2_RC_SUCCESS) {
-        return r;
-    }
+    return_state_if_error(r, _ESYS_STATE_INIT, "SAPI error on SetCmdAuths");
 
+    /* Trigger execution and finish the async invocation */
     r = Tss2_Sys_ExecuteAsync(esysContext->sys);
-    return_if_error(r, "Finish (Execute Async)");
+    return_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Finish (Execute Async)");
 
     esysContext->state = _ESYS_STATE_SENT;
 
@@ -248,32 +251,42 @@
     TPM2B_DIGEST **certInfo)
 {
     LOG_TRACE("complete");
+    TSS2_RC r;
     if (esysContext == NULL) {
         LOG_ERROR("esyscontext is NULL.");
         return TSS2_ESYS_RC_BAD_REFERENCE;
     }
+
+    /* Check for correct sequence and set sequence to irregular for now */
     if (esysContext->state != _ESYS_STATE_SENT) {
         LOG_ERROR("Esys called in bad sequence.");
         return TSS2_ESYS_RC_BAD_SEQUENCE;
     }
-    TSS2_RC r;
+    esysContext->state = _ESYS_STATE_INTERNALERROR;
+
+    /* Allocate memory for response parameters */
     if (certInfo != NULL) {
         *certInfo = calloc(sizeof(TPM2B_DIGEST), 1);
         if (*certInfo == NULL) {
             return_error(TSS2_ESYS_RC_MEMORY, "Out of memory");
         }
     }
+
+    /*Receive the TPM response and handle resubmissions if necessary. */
     r = Tss2_Sys_ExecuteFinish(esysContext->sys, esysContext->timeout);
     if ((r & ~TSS2_RC_LAYER_MASK) == TSS2_BASE_RC_TRY_AGAIN) {
         LOG_DEBUG("A layer below returned TRY_AGAIN: %" PRIx32, r);
+        esysContext->state = _ESYS_STATE_SENT;
         goto error_cleanup;
     }
+    /* This block handle the resubmission of TPM commands given a certain set of
+     * TPM response codes. */
     if (r == TPM2_RC_RETRY || r == TPM2_RC_TESTING || r == TPM2_RC_YIELDED) {
         LOG_DEBUG("TPM returned RETRY, TESTING or YIELDED, which triggers a "
             "resubmission: %" PRIx32, r);
         if (esysContext->submissionCount >= _ESYS_MAX_SUBMISSIONS) {
-            LOG_WARNING("Maximum number of resubmissions has been reached.");
-            esysContext->state = _ESYS_STATE_ERRORRESPONSE;
+            LOG_WARNING("Maximum number of (re)submissions has been reached.");
+            esysContext->state = _ESYS_STATE_INIT;
             goto error_cleanup;
         }
         esysContext->state = _ESYS_STATE_RESUBMISSION;
@@ -286,22 +299,32 @@
                 esysContext->in.ActivateCredential.credentialBlob,
                 esysContext->in.ActivateCredential.secret);
         if (r != TSS2_RC_SUCCESS) {
-            LOG_ERROR("Error attempting to resubmit");
+            LOG_WARNING("Error attempting to resubmit");
+            /* We do not set esysContext->state here but inherit the most recent
+             * state of the _async function. */
             goto error_cleanup;
         }
         r = TSS2_ESYS_RC_TRY_AGAIN;
+        LOG_DEBUG("Resubmission initiated and returning RC_TRY_AGAIN.");
         goto error_cleanup;
     }
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error finish (ExecuteFinish) ActivateCredential");
+    /* The following is the "regular error" handling. */
+    if (r != TSS2_RC_SUCCESS && (r & TSS2_RC_LAYER_MASK) == 0) {
+        LOG_WARNING("Received TPM Error");
+        esysContext->state = _ESYS_STATE_INIT;
+        goto error_cleanup;
+    } else if (r != TSS2_RC_SUCCESS) {
+        LOG_ERROR("Received a non-TPM Error");
+        esysContext->state = _ESYS_STATE_INTERNALERROR;
         goto error_cleanup;
     }
+
     /*
      * Now the verification of the response (hmac check) and if necessary the
-     * parameter decryption have to be done
+     * parameter decryption have to be done.
      */
     r = iesys_check_response(esysContext);
-    goto_if_error(r, "Error: check response",
+    goto_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Error: check response",
                       error_cleanup);
     /*
      * After the verification of the response we call the complete function
@@ -309,17 +332,17 @@
      */
     r = Tss2_Sys_ActivateCredential_Complete(esysContext->sys,
                 (certInfo != NULL) ? *certInfo : NULL);
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error finish (ExecuteFinish) ActivateCredential: %" PRIx32, r);
-        esysContext->state = _ESYS_STATE_ERRORRESPONSE;
-        goto error_cleanup;;
-    }
-    esysContext->state = _ESYS_STATE_FINISHED;
+    goto_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Received error from SAPI"
+                        " unmarshalling" ,error_cleanup);
+    esysContext->state = _ESYS_STATE_INIT;
+    LOG_DEBUG("context=%p, certInfo=%p",
+              esysContext, certInfo);
 
-    return r;
+    return TSS2_RC_SUCCESS;
 
 error_cleanup:
     if (certInfo != NULL)
         SAFE_FREE(*certInfo);
+
     return r;
 }
diff --git a/src/tss2-esys/api/Esys_Certify.c b/src/tss2-esys/api/Esys_Certify.c
index 8400681..3b99110 100644
--- a/src/tss2-esys/api/Esys_Certify.c
+++ b/src/tss2-esys/api/Esys_Certify.c
@@ -179,6 +179,7 @@
     RSRC_NODE_T *objectHandleNode;
     RSRC_NODE_T *signHandleNode;
 
+    /* Check context, sequence correctness and set state to error for now */
     if (esysContext == NULL) {
         LOG_ERROR("esyscontext is NULL.");
         return TSS2_ESYS_RC_BAD_REFERENCE;
@@ -186,46 +187,48 @@
     r = iesys_check_sequence_async(esysContext);
     if (r != TSS2_RC_SUCCESS)
         return r;
-    r = check_session_feasability(shandle1, shandle2, shandle3, 1);
-    return_if_error(r, "Check session usage");
+    esysContext->state = _ESYS_STATE_INTERNALERROR;
 
+    /* Check and store input parameters */
+    r = check_session_feasability(shandle1, shandle2, shandle3, 1);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Check session usage");
     store_input_parameters(esysContext, objectHandle, signHandle,
                 qualifyingData,
                 inScheme);
+
+    /* Retrieve the metadata objects for provided handles */
     r = esys_GetResourceObject(esysContext, objectHandle, &objectHandleNode);
-    if (r != TPM2_RC_SUCCESS)
-        return r;
+    return_state_if_error(r, _ESYS_STATE_INIT, "objectHandle unknown.");
     r = esys_GetResourceObject(esysContext, signHandle, &signHandleNode);
-    if (r != TPM2_RC_SUCCESS)
-        return r;
+    return_state_if_error(r, _ESYS_STATE_INIT, "signHandle unknown.");
+
+    /* Initial invocation of SAPI to prepare the command buffer with parameters */
     r = Tss2_Sys_Certify_Prepare(esysContext->sys,
                 (objectHandleNode == NULL) ? TPM2_RH_NULL : objectHandleNode->rsrc.handle,
                 (signHandleNode == NULL) ? TPM2_RH_NULL : signHandleNode->rsrc.handle,
                 qualifyingData,
                 inScheme);
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error async Certify");
-        return r;
-    }
-    r = init_session_tab(esysContext, shandle1, shandle2, shandle3);
-    return_if_error(r, "Initialize session resources");
+    return_state_if_error(r, _ESYS_STATE_INIT, "SAPI Prepare returned error.");
 
+    /* Calculate the cpHash Values */
+    r = init_session_tab(esysContext, shandle1, shandle2, shandle3);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Initialize session resources");
     iesys_compute_session_value(esysContext->session_tab[0],
                 &objectHandleNode->rsrc.name, &objectHandleNode->auth);
     iesys_compute_session_value(esysContext->session_tab[1],
                 &signHandleNode->rsrc.name, &signHandleNode->auth);
     iesys_compute_session_value(esysContext->session_tab[2], NULL, NULL);
-    r = iesys_gen_auths(esysContext, objectHandleNode, signHandleNode, NULL, &auths);
-    return_if_error(r, "Error in computation of auth values");
 
+    /* Generate the auth values and set them in the SAPI command buffer */
+    r = iesys_gen_auths(esysContext, objectHandleNode, signHandleNode, NULL, &auths);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Error in computation of auth values");
     esysContext->authsCount = auths.count;
     r = Tss2_Sys_SetCmdAuths(esysContext->sys, &auths);
-    if (r != TSS2_RC_SUCCESS) {
-        return r;
-    }
+    return_state_if_error(r, _ESYS_STATE_INIT, "SAPI error on SetCmdAuths");
 
+    /* Trigger execution and finish the async invocation */
     r = Tss2_Sys_ExecuteAsync(esysContext->sys);
-    return_if_error(r, "Finish (Execute Async)");
+    return_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Finish (Execute Async)");
 
     esysContext->state = _ESYS_STATE_SENT;
 
@@ -255,15 +258,20 @@
     TPMT_SIGNATURE **signature)
 {
     LOG_TRACE("complete");
+    TSS2_RC r;
     if (esysContext == NULL) {
         LOG_ERROR("esyscontext is NULL.");
         return TSS2_ESYS_RC_BAD_REFERENCE;
     }
+
+    /* Check for correct sequence and set sequence to irregular for now */
     if (esysContext->state != _ESYS_STATE_SENT) {
         LOG_ERROR("Esys called in bad sequence.");
         return TSS2_ESYS_RC_BAD_SEQUENCE;
     }
-    TSS2_RC r;
+    esysContext->state = _ESYS_STATE_INTERNALERROR;
+
+    /* Allocate memory for response parameters */
     if (certifyInfo != NULL) {
         *certifyInfo = calloc(sizeof(TPM2B_ATTEST), 1);
         if (*certifyInfo == NULL) {
@@ -276,17 +284,22 @@
             goto_error(r, TSS2_ESYS_RC_MEMORY, "Out of memory", error_cleanup);
         }
     }
+
+    /*Receive the TPM response and handle resubmissions if necessary. */
     r = Tss2_Sys_ExecuteFinish(esysContext->sys, esysContext->timeout);
     if ((r & ~TSS2_RC_LAYER_MASK) == TSS2_BASE_RC_TRY_AGAIN) {
         LOG_DEBUG("A layer below returned TRY_AGAIN: %" PRIx32, r);
+        esysContext->state = _ESYS_STATE_SENT;
         goto error_cleanup;
     }
+    /* This block handle the resubmission of TPM commands given a certain set of
+     * TPM response codes. */
     if (r == TPM2_RC_RETRY || r == TPM2_RC_TESTING || r == TPM2_RC_YIELDED) {
         LOG_DEBUG("TPM returned RETRY, TESTING or YIELDED, which triggers a "
             "resubmission: %" PRIx32, r);
         if (esysContext->submissionCount >= _ESYS_MAX_SUBMISSIONS) {
-            LOG_WARNING("Maximum number of resubmissions has been reached.");
-            esysContext->state = _ESYS_STATE_ERRORRESPONSE;
+            LOG_WARNING("Maximum number of (re)submissions has been reached.");
+            esysContext->state = _ESYS_STATE_INIT;
             goto error_cleanup;
         }
         esysContext->state = _ESYS_STATE_RESUBMISSION;
@@ -299,22 +312,32 @@
                 esysContext->in.Certify.qualifyingData,
                 esysContext->in.Certify.inScheme);
         if (r != TSS2_RC_SUCCESS) {
-            LOG_ERROR("Error attempting to resubmit");
+            LOG_WARNING("Error attempting to resubmit");
+            /* We do not set esysContext->state here but inherit the most recent
+             * state of the _async function. */
             goto error_cleanup;
         }
         r = TSS2_ESYS_RC_TRY_AGAIN;
+        LOG_DEBUG("Resubmission initiated and returning RC_TRY_AGAIN.");
         goto error_cleanup;
     }
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error finish (ExecuteFinish) Certify");
+    /* The following is the "regular error" handling. */
+    if (r != TSS2_RC_SUCCESS && (r & TSS2_RC_LAYER_MASK) == 0) {
+        LOG_WARNING("Received TPM Error");
+        esysContext->state = _ESYS_STATE_INIT;
+        goto error_cleanup;
+    } else if (r != TSS2_RC_SUCCESS) {
+        LOG_ERROR("Received a non-TPM Error");
+        esysContext->state = _ESYS_STATE_INTERNALERROR;
         goto error_cleanup;
     }
+
     /*
      * Now the verification of the response (hmac check) and if necessary the
-     * parameter decryption have to be done
+     * parameter decryption have to be done.
      */
     r = iesys_check_response(esysContext);
-    goto_if_error(r, "Error: check response",
+    goto_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Error: check response",
                       error_cleanup);
     /*
      * After the verification of the response we call the complete function
@@ -323,19 +346,19 @@
     r = Tss2_Sys_Certify_Complete(esysContext->sys,
                 (certifyInfo != NULL) ? *certifyInfo : NULL,
                 (signature != NULL) ? *signature : NULL);
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error finish (ExecuteFinish) Certify: %" PRIx32, r);
-        esysContext->state = _ESYS_STATE_ERRORRESPONSE;
-        goto error_cleanup;;
-    }
-    esysContext->state = _ESYS_STATE_FINISHED;
+    goto_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Received error from SAPI"
+                        " unmarshalling" ,error_cleanup);
+    esysContext->state = _ESYS_STATE_INIT;
+    LOG_DEBUG("context=%p, certifyInfo=%p, signature=%p",
+              esysContext, certifyInfo, signature);
 
-    return r;
+    return TSS2_RC_SUCCESS;
 
 error_cleanup:
     if (certifyInfo != NULL)
         SAFE_FREE(*certifyInfo);
     if (signature != NULL)
         SAFE_FREE(*signature);
+
     return r;
 }
diff --git a/src/tss2-esys/api/Esys_CertifyCreation.c b/src/tss2-esys/api/Esys_CertifyCreation.c
index ec31dcd..ba6796a 100644
--- a/src/tss2-esys/api/Esys_CertifyCreation.c
+++ b/src/tss2-esys/api/Esys_CertifyCreation.c
@@ -205,6 +205,7 @@
     RSRC_NODE_T *signHandleNode;
     RSRC_NODE_T *objectHandleNode;
 
+    /* Check context, sequence correctness and set state to error for now */
     if (esysContext == NULL) {
         LOG_ERROR("esyscontext is NULL.");
         return TSS2_ESYS_RC_BAD_REFERENCE;
@@ -212,20 +213,24 @@
     r = iesys_check_sequence_async(esysContext);
     if (r != TSS2_RC_SUCCESS)
         return r;
-    r = check_session_feasability(shandle1, shandle2, shandle3, 1);
-    return_if_error(r, "Check session usage");
+    esysContext->state = _ESYS_STATE_INTERNALERROR;
 
+    /* Check and store input parameters */
+    r = check_session_feasability(shandle1, shandle2, shandle3, 1);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Check session usage");
     store_input_parameters(esysContext, signHandle, objectHandle,
                 qualifyingData,
                 creationHash,
                 inScheme,
                 creationTicket);
+
+    /* Retrieve the metadata objects for provided handles */
     r = esys_GetResourceObject(esysContext, signHandle, &signHandleNode);
-    if (r != TPM2_RC_SUCCESS)
-        return r;
+    return_state_if_error(r, _ESYS_STATE_INIT, "signHandle unknown.");
     r = esys_GetResourceObject(esysContext, objectHandle, &objectHandleNode);
-    if (r != TPM2_RC_SUCCESS)
-        return r;
+    return_state_if_error(r, _ESYS_STATE_INIT, "objectHandle unknown.");
+
+    /* Initial invocation of SAPI to prepare the command buffer with parameters */
     r = Tss2_Sys_CertifyCreation_Prepare(esysContext->sys,
                 (signHandleNode == NULL) ? TPM2_RH_NULL : signHandleNode->rsrc.handle,
                 (objectHandleNode == NULL) ? TPM2_RH_NULL : objectHandleNode->rsrc.handle,
@@ -233,28 +238,26 @@
                 creationHash,
                 inScheme,
                 creationTicket);
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error async CertifyCreation");
-        return r;
-    }
-    r = init_session_tab(esysContext, shandle1, shandle2, shandle3);
-    return_if_error(r, "Initialize session resources");
+    return_state_if_error(r, _ESYS_STATE_INIT, "SAPI Prepare returned error.");
 
+    /* Calculate the cpHash Values */
+    r = init_session_tab(esysContext, shandle1, shandle2, shandle3);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Initialize session resources");
     iesys_compute_session_value(esysContext->session_tab[0],
                 &signHandleNode->rsrc.name, &signHandleNode->auth);
     iesys_compute_session_value(esysContext->session_tab[1], NULL, NULL);
     iesys_compute_session_value(esysContext->session_tab[2], NULL, NULL);
-    r = iesys_gen_auths(esysContext, signHandleNode, objectHandleNode, NULL, &auths);
-    return_if_error(r, "Error in computation of auth values");
 
+    /* Generate the auth values and set them in the SAPI command buffer */
+    r = iesys_gen_auths(esysContext, signHandleNode, objectHandleNode, NULL, &auths);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Error in computation of auth values");
     esysContext->authsCount = auths.count;
     r = Tss2_Sys_SetCmdAuths(esysContext->sys, &auths);
-    if (r != TSS2_RC_SUCCESS) {
-        return r;
-    }
+    return_state_if_error(r, _ESYS_STATE_INIT, "SAPI error on SetCmdAuths");
 
+    /* Trigger execution and finish the async invocation */
     r = Tss2_Sys_ExecuteAsync(esysContext->sys);
-    return_if_error(r, "Finish (Execute Async)");
+    return_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Finish (Execute Async)");
 
     esysContext->state = _ESYS_STATE_SENT;
 
@@ -284,15 +287,20 @@
     TPMT_SIGNATURE **signature)
 {
     LOG_TRACE("complete");
+    TSS2_RC r;
     if (esysContext == NULL) {
         LOG_ERROR("esyscontext is NULL.");
         return TSS2_ESYS_RC_BAD_REFERENCE;
     }
+
+    /* Check for correct sequence and set sequence to irregular for now */
     if (esysContext->state != _ESYS_STATE_SENT) {
         LOG_ERROR("Esys called in bad sequence.");
         return TSS2_ESYS_RC_BAD_SEQUENCE;
     }
-    TSS2_RC r;
+    esysContext->state = _ESYS_STATE_INTERNALERROR;
+
+    /* Allocate memory for response parameters */
     if (certifyInfo != NULL) {
         *certifyInfo = calloc(sizeof(TPM2B_ATTEST), 1);
         if (*certifyInfo == NULL) {
@@ -305,17 +313,22 @@
             goto_error(r, TSS2_ESYS_RC_MEMORY, "Out of memory", error_cleanup);
         }
     }
+
+    /*Receive the TPM response and handle resubmissions if necessary. */
     r = Tss2_Sys_ExecuteFinish(esysContext->sys, esysContext->timeout);
     if ((r & ~TSS2_RC_LAYER_MASK) == TSS2_BASE_RC_TRY_AGAIN) {
         LOG_DEBUG("A layer below returned TRY_AGAIN: %" PRIx32, r);
+        esysContext->state = _ESYS_STATE_SENT;
         goto error_cleanup;
     }
+    /* This block handle the resubmission of TPM commands given a certain set of
+     * TPM response codes. */
     if (r == TPM2_RC_RETRY || r == TPM2_RC_TESTING || r == TPM2_RC_YIELDED) {
         LOG_DEBUG("TPM returned RETRY, TESTING or YIELDED, which triggers a "
             "resubmission: %" PRIx32, r);
         if (esysContext->submissionCount >= _ESYS_MAX_SUBMISSIONS) {
-            LOG_WARNING("Maximum number of resubmissions has been reached.");
-            esysContext->state = _ESYS_STATE_ERRORRESPONSE;
+            LOG_WARNING("Maximum number of (re)submissions has been reached.");
+            esysContext->state = _ESYS_STATE_INIT;
             goto error_cleanup;
         }
         esysContext->state = _ESYS_STATE_RESUBMISSION;
@@ -330,22 +343,32 @@
                 esysContext->in.CertifyCreation.inScheme,
                 esysContext->in.CertifyCreation.creationTicket);
         if (r != TSS2_RC_SUCCESS) {
-            LOG_ERROR("Error attempting to resubmit");
+            LOG_WARNING("Error attempting to resubmit");
+            /* We do not set esysContext->state here but inherit the most recent
+             * state of the _async function. */
             goto error_cleanup;
         }
         r = TSS2_ESYS_RC_TRY_AGAIN;
+        LOG_DEBUG("Resubmission initiated and returning RC_TRY_AGAIN.");
         goto error_cleanup;
     }
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error finish (ExecuteFinish) CertifyCreation");
+    /* The following is the "regular error" handling. */
+    if (r != TSS2_RC_SUCCESS && (r & TSS2_RC_LAYER_MASK) == 0) {
+        LOG_WARNING("Received TPM Error");
+        esysContext->state = _ESYS_STATE_INIT;
+        goto error_cleanup;
+    } else if (r != TSS2_RC_SUCCESS) {
+        LOG_ERROR("Received a non-TPM Error");
+        esysContext->state = _ESYS_STATE_INTERNALERROR;
         goto error_cleanup;
     }
+
     /*
      * Now the verification of the response (hmac check) and if necessary the
-     * parameter decryption have to be done
+     * parameter decryption have to be done.
      */
     r = iesys_check_response(esysContext);
-    goto_if_error(r, "Error: check response",
+    goto_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Error: check response",
                       error_cleanup);
     /*
      * After the verification of the response we call the complete function
@@ -354,19 +377,19 @@
     r = Tss2_Sys_CertifyCreation_Complete(esysContext->sys,
                 (certifyInfo != NULL) ? *certifyInfo : NULL,
                 (signature != NULL) ? *signature : NULL);
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error finish (ExecuteFinish) CertifyCreation: %" PRIx32, r);
-        esysContext->state = _ESYS_STATE_ERRORRESPONSE;
-        goto error_cleanup;;
-    }
-    esysContext->state = _ESYS_STATE_FINISHED;
+    goto_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Received error from SAPI"
+                        " unmarshalling" ,error_cleanup);
+    esysContext->state = _ESYS_STATE_INIT;
+    LOG_DEBUG("context=%p, certifyInfo=%p, signature=%p",
+              esysContext, certifyInfo, signature);
 
-    return r;
+    return TSS2_RC_SUCCESS;
 
 error_cleanup:
     if (certifyInfo != NULL)
         SAFE_FREE(*certifyInfo);
     if (signature != NULL)
         SAFE_FREE(*signature);
+
     return r;
 }
diff --git a/src/tss2-esys/api/Esys_ChangeEPS.c b/src/tss2-esys/api/Esys_ChangeEPS.c
index 98d9523..8325e44 100644
--- a/src/tss2-esys/api/Esys_ChangeEPS.c
+++ b/src/tss2-esys/api/Esys_ChangeEPS.c
@@ -135,6 +135,7 @@
     TSS2L_SYS_AUTH_COMMAND auths;
     RSRC_NODE_T *authHandleNode;
 
+    /* Check context, sequence correctness and set state to error for now */
     if (esysContext == NULL) {
         LOG_ERROR("esyscontext is NULL.");
         return TSS2_ESYS_RC_BAD_REFERENCE;
@@ -142,35 +143,40 @@
     r = iesys_check_sequence_async(esysContext);
     if (r != TSS2_RC_SUCCESS)
         return r;
-    r = check_session_feasability(shandle1, shandle2, shandle3, 1);
-    return_if_error(r, "Check session usage");
+    esysContext->state = _ESYS_STATE_INTERNALERROR;
 
+    /* Check and store input parameters */
+    r = check_session_feasability(shandle1, shandle2, shandle3, 1);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Check session usage");
     store_input_parameters(esysContext, authHandle);
+
+    /* Retrieve the metadata objects for provided handles */
     r = esys_GetResourceObject(esysContext, authHandle, &authHandleNode);
-    if (r != TPM2_RC_SUCCESS)
-        return r;
+    return_state_if_error(r, _ESYS_STATE_INIT, "authHandle unknown.");
+
+    /* Initial invocation of SAPI to prepare the command buffer with parameters */
     r = Tss2_Sys_ChangeEPS_Prepare(esysContext->sys,
                 (authHandleNode == NULL) ? TPM2_RH_NULL : authHandleNode->rsrc.handle);
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error async ChangeEPS");
-        return r;
-    }
-    r = init_session_tab(esysContext, shandle1, shandle2, shandle3);
-    return_if_error(r, "Initialize session resources");
+    return_state_if_error(r, _ESYS_STATE_INIT, "SAPI Prepare returned error.");
 
+    /* Calculate the cpHash Values */
+    r = init_session_tab(esysContext, shandle1, shandle2, shandle3);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Initialize session resources");
     iesys_compute_session_value(esysContext->session_tab[0],
                 &authHandleNode->rsrc.name, &authHandleNode->auth);
-    r = iesys_gen_auths(esysContext, authHandleNode, NULL, NULL, &auths);
-    return_if_error(r, "Error in computation of auth values");
+    iesys_compute_session_value(esysContext->session_tab[1], NULL, NULL);
+    iesys_compute_session_value(esysContext->session_tab[2], NULL, NULL);
 
+    /* Generate the auth values and set them in the SAPI command buffer */
+    r = iesys_gen_auths(esysContext, authHandleNode, NULL, NULL, &auths);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Error in computation of auth values");
     esysContext->authsCount = auths.count;
     r = Tss2_Sys_SetCmdAuths(esysContext->sys, &auths);
-    if (r != TSS2_RC_SUCCESS) {
-        return r;
-    }
+    return_state_if_error(r, _ESYS_STATE_INIT, "SAPI error on SetCmdAuths");
 
+    /* Trigger execution and finish the async invocation */
     r = Tss2_Sys_ExecuteAsync(esysContext->sys);
-    return_if_error(r, "Finish (Execute Async)");
+    return_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Finish (Execute Async)");
 
     esysContext->state = _ESYS_STATE_SENT;
 
@@ -194,26 +200,34 @@
     ESYS_CONTEXT *esysContext)
 {
     LOG_TRACE("complete");
+    TSS2_RC r;
     if (esysContext == NULL) {
         LOG_ERROR("esyscontext is NULL.");
         return TSS2_ESYS_RC_BAD_REFERENCE;
     }
+
+    /* Check for correct sequence and set sequence to irregular for now */
     if (esysContext->state != _ESYS_STATE_SENT) {
         LOG_ERROR("Esys called in bad sequence.");
         return TSS2_ESYS_RC_BAD_SEQUENCE;
     }
-    TSS2_RC r;
+    esysContext->state = _ESYS_STATE_INTERNALERROR;
+
+    /*Receive the TPM response and handle resubmissions if necessary. */
     r = Tss2_Sys_ExecuteFinish(esysContext->sys, esysContext->timeout);
     if ((r & ~TSS2_RC_LAYER_MASK) == TSS2_BASE_RC_TRY_AGAIN) {
         LOG_DEBUG("A layer below returned TRY_AGAIN: %" PRIx32, r);
+        esysContext->state = _ESYS_STATE_SENT;
         return r;
     }
+    /* This block handle the resubmission of TPM commands given a certain set of
+     * TPM response codes. */
     if (r == TPM2_RC_RETRY || r == TPM2_RC_TESTING || r == TPM2_RC_YIELDED) {
         LOG_DEBUG("TPM returned RETRY, TESTING or YIELDED, which triggers a "
             "resubmission: %" PRIx32, r);
         if (esysContext->submissionCount >= _ESYS_MAX_SUBMISSIONS) {
-            LOG_WARNING("Maximum number of resubmissions has been reached.");
-            esysContext->state = _ESYS_STATE_ERRORRESPONSE;
+            LOG_WARNING("Maximum number of (re)submissions has been reached.");
+            esysContext->state = _ESYS_STATE_INIT;
             return r;
         }
         esysContext->state = _ESYS_STATE_RESUBMISSION;
@@ -223,33 +237,42 @@
                 esysContext->session_type[1],
                 esysContext->session_type[2]);
         if (r != TSS2_RC_SUCCESS) {
-            LOG_ERROR("Error attempting to resubmit");
+            LOG_WARNING("Error attempting to resubmit");
+            /* We do not set esysContext->state here but inherit the most recent
+             * state of the _async function. */
             return r;
         }
         r = TSS2_ESYS_RC_TRY_AGAIN;
+        LOG_DEBUG("Resubmission initiated and returning RC_TRY_AGAIN.");
         return r;
     }
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error finish (ExecuteFinish) ChangeEPS");
+    /* The following is the "regular error" handling. */
+    if (r != TSS2_RC_SUCCESS && (r & TSS2_RC_LAYER_MASK) == 0) {
+        LOG_WARNING("Received TPM Error");
+        esysContext->state = _ESYS_STATE_INIT;
+        return r;
+    } else if (r != TSS2_RC_SUCCESS) {
+        LOG_ERROR("Received a non-TPM Error");
+        esysContext->state = _ESYS_STATE_INTERNALERROR;
         return r;
     }
+
     /*
      * Now the verification of the response (hmac check) and if necessary the
-     * parameter decryption have to be done
+     * parameter decryption have to be done.
      */
     r = iesys_check_response(esysContext);
-    return_if_error(r, "Error: check response");
+    return_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Error: check response");
     /*
      * After the verification of the response we call the complete function
      * to deliver the result.
      */
     r = Tss2_Sys_ChangeEPS_Complete(esysContext->sys);
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error finish (ExecuteFinish) ChangeEPS: %" PRIx32, r);
-        esysContext->state = _ESYS_STATE_ERRORRESPONSE;
-        return r;;
-    }
-    esysContext->state = _ESYS_STATE_FINISHED;
+    return_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Received error from SAPI"
+                        " unmarshalling" );
+    esysContext->state = _ESYS_STATE_INIT;
+    LOG_DEBUG("context=%p",
+              esysContext);
 
-    return r;
+    return TSS2_RC_SUCCESS;
 }
diff --git a/src/tss2-esys/api/Esys_ChangePPS.c b/src/tss2-esys/api/Esys_ChangePPS.c
index 3662f37..470199e 100644
--- a/src/tss2-esys/api/Esys_ChangePPS.c
+++ b/src/tss2-esys/api/Esys_ChangePPS.c
@@ -135,6 +135,7 @@
     TSS2L_SYS_AUTH_COMMAND auths;
     RSRC_NODE_T *authHandleNode;
 
+    /* Check context, sequence correctness and set state to error for now */
     if (esysContext == NULL) {
         LOG_ERROR("esyscontext is NULL.");
         return TSS2_ESYS_RC_BAD_REFERENCE;
@@ -142,35 +143,40 @@
     r = iesys_check_sequence_async(esysContext);
     if (r != TSS2_RC_SUCCESS)
         return r;
-    r = check_session_feasability(shandle1, shandle2, shandle3, 1);
-    return_if_error(r, "Check session usage");
+    esysContext->state = _ESYS_STATE_INTERNALERROR;
 
+    /* Check and store input parameters */
+    r = check_session_feasability(shandle1, shandle2, shandle3, 1);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Check session usage");
     store_input_parameters(esysContext, authHandle);
+
+    /* Retrieve the metadata objects for provided handles */
     r = esys_GetResourceObject(esysContext, authHandle, &authHandleNode);
-    if (r != TPM2_RC_SUCCESS)
-        return r;
+    return_state_if_error(r, _ESYS_STATE_INIT, "authHandle unknown.");
+
+    /* Initial invocation of SAPI to prepare the command buffer with parameters */
     r = Tss2_Sys_ChangePPS_Prepare(esysContext->sys,
                 (authHandleNode == NULL) ? TPM2_RH_NULL : authHandleNode->rsrc.handle);
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error async ChangePPS");
-        return r;
-    }
-    r = init_session_tab(esysContext, shandle1, shandle2, shandle3);
-    return_if_error(r, "Initialize session resources");
+    return_state_if_error(r, _ESYS_STATE_INIT, "SAPI Prepare returned error.");
 
+    /* Calculate the cpHash Values */
+    r = init_session_tab(esysContext, shandle1, shandle2, shandle3);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Initialize session resources");
     iesys_compute_session_value(esysContext->session_tab[0],
                 &authHandleNode->rsrc.name, &authHandleNode->auth);
-    r = iesys_gen_auths(esysContext, authHandleNode, NULL, NULL, &auths);
-    return_if_error(r, "Error in computation of auth values");
+    iesys_compute_session_value(esysContext->session_tab[1], NULL, NULL);
+    iesys_compute_session_value(esysContext->session_tab[2], NULL, NULL);
 
+    /* Generate the auth values and set them in the SAPI command buffer */
+    r = iesys_gen_auths(esysContext, authHandleNode, NULL, NULL, &auths);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Error in computation of auth values");
     esysContext->authsCount = auths.count;
     r = Tss2_Sys_SetCmdAuths(esysContext->sys, &auths);
-    if (r != TSS2_RC_SUCCESS) {
-        return r;
-    }
+    return_state_if_error(r, _ESYS_STATE_INIT, "SAPI error on SetCmdAuths");
 
+    /* Trigger execution and finish the async invocation */
     r = Tss2_Sys_ExecuteAsync(esysContext->sys);
-    return_if_error(r, "Finish (Execute Async)");
+    return_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Finish (Execute Async)");
 
     esysContext->state = _ESYS_STATE_SENT;
 
@@ -194,26 +200,34 @@
     ESYS_CONTEXT *esysContext)
 {
     LOG_TRACE("complete");
+    TSS2_RC r;
     if (esysContext == NULL) {
         LOG_ERROR("esyscontext is NULL.");
         return TSS2_ESYS_RC_BAD_REFERENCE;
     }
+
+    /* Check for correct sequence and set sequence to irregular for now */
     if (esysContext->state != _ESYS_STATE_SENT) {
         LOG_ERROR("Esys called in bad sequence.");
         return TSS2_ESYS_RC_BAD_SEQUENCE;
     }
-    TSS2_RC r;
+    esysContext->state = _ESYS_STATE_INTERNALERROR;
+
+    /*Receive the TPM response and handle resubmissions if necessary. */
     r = Tss2_Sys_ExecuteFinish(esysContext->sys, esysContext->timeout);
     if ((r & ~TSS2_RC_LAYER_MASK) == TSS2_BASE_RC_TRY_AGAIN) {
         LOG_DEBUG("A layer below returned TRY_AGAIN: %" PRIx32, r);
+        esysContext->state = _ESYS_STATE_SENT;
         return r;
     }
+    /* This block handle the resubmission of TPM commands given a certain set of
+     * TPM response codes. */
     if (r == TPM2_RC_RETRY || r == TPM2_RC_TESTING || r == TPM2_RC_YIELDED) {
         LOG_DEBUG("TPM returned RETRY, TESTING or YIELDED, which triggers a "
             "resubmission: %" PRIx32, r);
         if (esysContext->submissionCount >= _ESYS_MAX_SUBMISSIONS) {
-            LOG_WARNING("Maximum number of resubmissions has been reached.");
-            esysContext->state = _ESYS_STATE_ERRORRESPONSE;
+            LOG_WARNING("Maximum number of (re)submissions has been reached.");
+            esysContext->state = _ESYS_STATE_INIT;
             return r;
         }
         esysContext->state = _ESYS_STATE_RESUBMISSION;
@@ -223,33 +237,42 @@
                 esysContext->session_type[1],
                 esysContext->session_type[2]);
         if (r != TSS2_RC_SUCCESS) {
-            LOG_ERROR("Error attempting to resubmit");
+            LOG_WARNING("Error attempting to resubmit");
+            /* We do not set esysContext->state here but inherit the most recent
+             * state of the _async function. */
             return r;
         }
         r = TSS2_ESYS_RC_TRY_AGAIN;
+        LOG_DEBUG("Resubmission initiated and returning RC_TRY_AGAIN.");
         return r;
     }
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error finish (ExecuteFinish) ChangePPS");
+    /* The following is the "regular error" handling. */
+    if (r != TSS2_RC_SUCCESS && (r & TSS2_RC_LAYER_MASK) == 0) {
+        LOG_WARNING("Received TPM Error");
+        esysContext->state = _ESYS_STATE_INIT;
+        return r;
+    } else if (r != TSS2_RC_SUCCESS) {
+        LOG_ERROR("Received a non-TPM Error");
+        esysContext->state = _ESYS_STATE_INTERNALERROR;
         return r;
     }
+
     /*
      * Now the verification of the response (hmac check) and if necessary the
-     * parameter decryption have to be done
+     * parameter decryption have to be done.
      */
     r = iesys_check_response(esysContext);
-    return_if_error(r, "Error: check response");
+    return_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Error: check response");
     /*
      * After the verification of the response we call the complete function
      * to deliver the result.
      */
     r = Tss2_Sys_ChangePPS_Complete(esysContext->sys);
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error finish (ExecuteFinish) ChangePPS: %" PRIx32, r);
-        esysContext->state = _ESYS_STATE_ERRORRESPONSE;
-        return r;;
-    }
-    esysContext->state = _ESYS_STATE_FINISHED;
+    return_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Received error from SAPI"
+                        " unmarshalling" );
+    esysContext->state = _ESYS_STATE_INIT;
+    LOG_DEBUG("context=%p",
+              esysContext);
 
-    return r;
+    return TSS2_RC_SUCCESS;
 }
diff --git a/src/tss2-esys/api/Esys_Clear.c b/src/tss2-esys/api/Esys_Clear.c
index 8d89162..ca5ae1a 100644
--- a/src/tss2-esys/api/Esys_Clear.c
+++ b/src/tss2-esys/api/Esys_Clear.c
@@ -135,6 +135,7 @@
     TSS2L_SYS_AUTH_COMMAND auths;
     RSRC_NODE_T *authHandleNode;
 
+    /* Check context, sequence correctness and set state to error for now */
     if (esysContext == NULL) {
         LOG_ERROR("esyscontext is NULL.");
         return TSS2_ESYS_RC_BAD_REFERENCE;
@@ -142,35 +143,40 @@
     r = iesys_check_sequence_async(esysContext);
     if (r != TSS2_RC_SUCCESS)
         return r;
-    r = check_session_feasability(shandle1, shandle2, shandle3, 1);
-    return_if_error(r, "Check session usage");
+    esysContext->state = _ESYS_STATE_INTERNALERROR;
 
+    /* Check and store input parameters */
+    r = check_session_feasability(shandle1, shandle2, shandle3, 1);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Check session usage");
     store_input_parameters(esysContext, authHandle);
+
+    /* Retrieve the metadata objects for provided handles */
     r = esys_GetResourceObject(esysContext, authHandle, &authHandleNode);
-    if (r != TPM2_RC_SUCCESS)
-        return r;
+    return_state_if_error(r, _ESYS_STATE_INIT, "authHandle unknown.");
+
+    /* Initial invocation of SAPI to prepare the command buffer with parameters */
     r = Tss2_Sys_Clear_Prepare(esysContext->sys,
                 (authHandleNode == NULL) ? TPM2_RH_NULL : authHandleNode->rsrc.handle);
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error async Clear");
-        return r;
-    }
-    r = init_session_tab(esysContext, shandle1, shandle2, shandle3);
-    return_if_error(r, "Initialize session resources");
+    return_state_if_error(r, _ESYS_STATE_INIT, "SAPI Prepare returned error.");
 
+    /* Calculate the cpHash Values */
+    r = init_session_tab(esysContext, shandle1, shandle2, shandle3);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Initialize session resources");
     iesys_compute_session_value(esysContext->session_tab[0],
                 &authHandleNode->rsrc.name, &authHandleNode->auth);
-    r = iesys_gen_auths(esysContext, authHandleNode, NULL, NULL, &auths);
-    return_if_error(r, "Error in computation of auth values");
+    iesys_compute_session_value(esysContext->session_tab[1], NULL, NULL);
+    iesys_compute_session_value(esysContext->session_tab[2], NULL, NULL);
 
+    /* Generate the auth values and set them in the SAPI command buffer */
+    r = iesys_gen_auths(esysContext, authHandleNode, NULL, NULL, &auths);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Error in computation of auth values");
     esysContext->authsCount = auths.count;
     r = Tss2_Sys_SetCmdAuths(esysContext->sys, &auths);
-    if (r != TSS2_RC_SUCCESS) {
-        return r;
-    }
+    return_state_if_error(r, _ESYS_STATE_INIT, "SAPI error on SetCmdAuths");
 
+    /* Trigger execution and finish the async invocation */
     r = Tss2_Sys_ExecuteAsync(esysContext->sys);
-    return_if_error(r, "Finish (Execute Async)");
+    return_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Finish (Execute Async)");
 
     esysContext->state = _ESYS_STATE_SENT;
 
@@ -194,26 +200,34 @@
     ESYS_CONTEXT *esysContext)
 {
     LOG_TRACE("complete");
+    TSS2_RC r;
     if (esysContext == NULL) {
         LOG_ERROR("esyscontext is NULL.");
         return TSS2_ESYS_RC_BAD_REFERENCE;
     }
+
+    /* Check for correct sequence and set sequence to irregular for now */
     if (esysContext->state != _ESYS_STATE_SENT) {
         LOG_ERROR("Esys called in bad sequence.");
         return TSS2_ESYS_RC_BAD_SEQUENCE;
     }
-    TSS2_RC r;
+    esysContext->state = _ESYS_STATE_INTERNALERROR;
+
+    /*Receive the TPM response and handle resubmissions if necessary. */
     r = Tss2_Sys_ExecuteFinish(esysContext->sys, esysContext->timeout);
     if ((r & ~TSS2_RC_LAYER_MASK) == TSS2_BASE_RC_TRY_AGAIN) {
         LOG_DEBUG("A layer below returned TRY_AGAIN: %" PRIx32, r);
+        esysContext->state = _ESYS_STATE_SENT;
         return r;
     }
+    /* This block handle the resubmission of TPM commands given a certain set of
+     * TPM response codes. */
     if (r == TPM2_RC_RETRY || r == TPM2_RC_TESTING || r == TPM2_RC_YIELDED) {
         LOG_DEBUG("TPM returned RETRY, TESTING or YIELDED, which triggers a "
             "resubmission: %" PRIx32, r);
         if (esysContext->submissionCount >= _ESYS_MAX_SUBMISSIONS) {
-            LOG_WARNING("Maximum number of resubmissions has been reached.");
-            esysContext->state = _ESYS_STATE_ERRORRESPONSE;
+            LOG_WARNING("Maximum number of (re)submissions has been reached.");
+            esysContext->state = _ESYS_STATE_INIT;
             return r;
         }
         esysContext->state = _ESYS_STATE_RESUBMISSION;
@@ -223,33 +237,42 @@
                 esysContext->session_type[1],
                 esysContext->session_type[2]);
         if (r != TSS2_RC_SUCCESS) {
-            LOG_ERROR("Error attempting to resubmit");
+            LOG_WARNING("Error attempting to resubmit");
+            /* We do not set esysContext->state here but inherit the most recent
+             * state of the _async function. */
             return r;
         }
         r = TSS2_ESYS_RC_TRY_AGAIN;
+        LOG_DEBUG("Resubmission initiated and returning RC_TRY_AGAIN.");
         return r;
     }
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error finish (ExecuteFinish) Clear");
+    /* The following is the "regular error" handling. */
+    if (r != TSS2_RC_SUCCESS && (r & TSS2_RC_LAYER_MASK) == 0) {
+        LOG_WARNING("Received TPM Error");
+        esysContext->state = _ESYS_STATE_INIT;
+        return r;
+    } else if (r != TSS2_RC_SUCCESS) {
+        LOG_ERROR("Received a non-TPM Error");
+        esysContext->state = _ESYS_STATE_INTERNALERROR;
         return r;
     }
+
     /*
      * Now the verification of the response (hmac check) and if necessary the
-     * parameter decryption have to be done
+     * parameter decryption have to be done.
      */
     r = iesys_check_response(esysContext);
-    return_if_error(r, "Error: check response");
+    return_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Error: check response");
     /*
      * After the verification of the response we call the complete function
      * to deliver the result.
      */
     r = Tss2_Sys_Clear_Complete(esysContext->sys);
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error finish (ExecuteFinish) Clear: %" PRIx32, r);
-        esysContext->state = _ESYS_STATE_ERRORRESPONSE;
-        return r;;
-    }
-    esysContext->state = _ESYS_STATE_FINISHED;
+    return_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Received error from SAPI"
+                        " unmarshalling" );
+    esysContext->state = _ESYS_STATE_INIT;
+    LOG_DEBUG("context=%p",
+              esysContext);
 
-    return r;
+    return TSS2_RC_SUCCESS;
 }
diff --git a/src/tss2-esys/api/Esys_ClearControl.c b/src/tss2-esys/api/Esys_ClearControl.c
index 49d98bd..f22cb2e 100644
--- a/src/tss2-esys/api/Esys_ClearControl.c
+++ b/src/tss2-esys/api/Esys_ClearControl.c
@@ -142,6 +142,7 @@
     TSS2L_SYS_AUTH_COMMAND auths;
     RSRC_NODE_T *authNode;
 
+    /* Check context, sequence correctness and set state to error for now */
     if (esysContext == NULL) {
         LOG_ERROR("esyscontext is NULL.");
         return TSS2_ESYS_RC_BAD_REFERENCE;
@@ -149,38 +150,42 @@
     r = iesys_check_sequence_async(esysContext);
     if (r != TSS2_RC_SUCCESS)
         return r;
-    r = check_session_feasability(shandle1, shandle2, shandle3, 1);
-    return_if_error(r, "Check session usage");
+    esysContext->state = _ESYS_STATE_INTERNALERROR;
 
+    /* Check and store input parameters */
+    r = check_session_feasability(shandle1, shandle2, shandle3, 1);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Check session usage");
     store_input_parameters(esysContext, auth,
                 disable);
+
+    /* Retrieve the metadata objects for provided handles */
     r = esys_GetResourceObject(esysContext, auth, &authNode);
-    if (r != TPM2_RC_SUCCESS)
-        return r;
+    return_state_if_error(r, _ESYS_STATE_INIT, "auth unknown.");
+
+    /* Initial invocation of SAPI to prepare the command buffer with parameters */
     r = Tss2_Sys_ClearControl_Prepare(esysContext->sys,
                 (authNode == NULL) ? TPM2_RH_NULL : authNode->rsrc.handle,
                 disable);
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error async ClearControl");
-        return r;
-    }
-    r = init_session_tab(esysContext, shandle1, shandle2, shandle3);
-    return_if_error(r, "Initialize session resources");
+    return_state_if_error(r, _ESYS_STATE_INIT, "SAPI Prepare returned error.");
 
+    /* Calculate the cpHash Values */
+    r = init_session_tab(esysContext, shandle1, shandle2, shandle3);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Initialize session resources");
     iesys_compute_session_value(esysContext->session_tab[0],
                 &authNode->rsrc.name, &authNode->auth);
     iesys_compute_session_value(esysContext->session_tab[1], NULL, NULL);
-    r = iesys_gen_auths(esysContext, authNode, NULL, NULL, &auths);
-    return_if_error(r, "Error in computation of auth values");
+    iesys_compute_session_value(esysContext->session_tab[2], NULL, NULL);
 
+    /* Generate the auth values and set them in the SAPI command buffer */
+    r = iesys_gen_auths(esysContext, authNode, NULL, NULL, &auths);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Error in computation of auth values");
     esysContext->authsCount = auths.count;
     r = Tss2_Sys_SetCmdAuths(esysContext->sys, &auths);
-    if (r != TSS2_RC_SUCCESS) {
-        return r;
-    }
+    return_state_if_error(r, _ESYS_STATE_INIT, "SAPI error on SetCmdAuths");
 
+    /* Trigger execution and finish the async invocation */
     r = Tss2_Sys_ExecuteAsync(esysContext->sys);
-    return_if_error(r, "Finish (Execute Async)");
+    return_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Finish (Execute Async)");
 
     esysContext->state = _ESYS_STATE_SENT;
 
@@ -204,26 +209,34 @@
     ESYS_CONTEXT *esysContext)
 {
     LOG_TRACE("complete");
+    TSS2_RC r;
     if (esysContext == NULL) {
         LOG_ERROR("esyscontext is NULL.");
         return TSS2_ESYS_RC_BAD_REFERENCE;
     }
+
+    /* Check for correct sequence and set sequence to irregular for now */
     if (esysContext->state != _ESYS_STATE_SENT) {
         LOG_ERROR("Esys called in bad sequence.");
         return TSS2_ESYS_RC_BAD_SEQUENCE;
     }
-    TSS2_RC r;
+    esysContext->state = _ESYS_STATE_INTERNALERROR;
+
+    /*Receive the TPM response and handle resubmissions if necessary. */
     r = Tss2_Sys_ExecuteFinish(esysContext->sys, esysContext->timeout);
     if ((r & ~TSS2_RC_LAYER_MASK) == TSS2_BASE_RC_TRY_AGAIN) {
         LOG_DEBUG("A layer below returned TRY_AGAIN: %" PRIx32, r);
+        esysContext->state = _ESYS_STATE_SENT;
         return r;
     }
+    /* This block handle the resubmission of TPM commands given a certain set of
+     * TPM response codes. */
     if (r == TPM2_RC_RETRY || r == TPM2_RC_TESTING || r == TPM2_RC_YIELDED) {
         LOG_DEBUG("TPM returned RETRY, TESTING or YIELDED, which triggers a "
             "resubmission: %" PRIx32, r);
         if (esysContext->submissionCount >= _ESYS_MAX_SUBMISSIONS) {
-            LOG_WARNING("Maximum number of resubmissions has been reached.");
-            esysContext->state = _ESYS_STATE_ERRORRESPONSE;
+            LOG_WARNING("Maximum number of (re)submissions has been reached.");
+            esysContext->state = _ESYS_STATE_INIT;
             return r;
         }
         esysContext->state = _ESYS_STATE_RESUBMISSION;
@@ -234,33 +247,42 @@
                 esysContext->session_type[2],
                 esysContext->in.ClearControl.disable);
         if (r != TSS2_RC_SUCCESS) {
-            LOG_ERROR("Error attempting to resubmit");
+            LOG_WARNING("Error attempting to resubmit");
+            /* We do not set esysContext->state here but inherit the most recent
+             * state of the _async function. */
             return r;
         }
         r = TSS2_ESYS_RC_TRY_AGAIN;
+        LOG_DEBUG("Resubmission initiated and returning RC_TRY_AGAIN.");
         return r;
     }
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error finish (ExecuteFinish) ClearControl");
+    /* The following is the "regular error" handling. */
+    if (r != TSS2_RC_SUCCESS && (r & TSS2_RC_LAYER_MASK) == 0) {
+        LOG_WARNING("Received TPM Error");
+        esysContext->state = _ESYS_STATE_INIT;
+        return r;
+    } else if (r != TSS2_RC_SUCCESS) {
+        LOG_ERROR("Received a non-TPM Error");
+        esysContext->state = _ESYS_STATE_INTERNALERROR;
         return r;
     }
+
     /*
      * Now the verification of the response (hmac check) and if necessary the
-     * parameter decryption have to be done
+     * parameter decryption have to be done.
      */
     r = iesys_check_response(esysContext);
-    return_if_error(r, "Error: check response");
+    return_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Error: check response");
     /*
      * After the verification of the response we call the complete function
      * to deliver the result.
      */
     r = Tss2_Sys_ClearControl_Complete(esysContext->sys);
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error finish (ExecuteFinish) ClearControl: %" PRIx32, r);
-        esysContext->state = _ESYS_STATE_ERRORRESPONSE;
-        return r;;
-    }
-    esysContext->state = _ESYS_STATE_FINISHED;
+    return_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Received error from SAPI"
+                        " unmarshalling" );
+    esysContext->state = _ESYS_STATE_INIT;
+    LOG_DEBUG("context=%p",
+              esysContext);
 
-    return r;
+    return TSS2_RC_SUCCESS;
 }
diff --git a/src/tss2-esys/api/Esys_ClockRateAdjust.c b/src/tss2-esys/api/Esys_ClockRateAdjust.c
index 38e255f..76dd7cd 100644
--- a/src/tss2-esys/api/Esys_ClockRateAdjust.c
+++ b/src/tss2-esys/api/Esys_ClockRateAdjust.c
@@ -142,6 +142,7 @@
     TSS2L_SYS_AUTH_COMMAND auths;
     RSRC_NODE_T *authNode;
 
+    /* Check context, sequence correctness and set state to error for now */
     if (esysContext == NULL) {
         LOG_ERROR("esyscontext is NULL.");
         return TSS2_ESYS_RC_BAD_REFERENCE;
@@ -149,38 +150,42 @@
     r = iesys_check_sequence_async(esysContext);
     if (r != TSS2_RC_SUCCESS)
         return r;
-    r = check_session_feasability(shandle1, shandle2, shandle3, 1);
-    return_if_error(r, "Check session usage");
+    esysContext->state = _ESYS_STATE_INTERNALERROR;
 
+    /* Check and store input parameters */
+    r = check_session_feasability(shandle1, shandle2, shandle3, 1);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Check session usage");
     store_input_parameters(esysContext, auth,
                 rateAdjust);
+
+    /* Retrieve the metadata objects for provided handles */
     r = esys_GetResourceObject(esysContext, auth, &authNode);
-    if (r != TPM2_RC_SUCCESS)
-        return r;
+    return_state_if_error(r, _ESYS_STATE_INIT, "auth unknown.");
+
+    /* Initial invocation of SAPI to prepare the command buffer with parameters */
     r = Tss2_Sys_ClockRateAdjust_Prepare(esysContext->sys,
                 (authNode == NULL) ? TPM2_RH_NULL : authNode->rsrc.handle,
                 rateAdjust);
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error async ClockRateAdjust");
-        return r;
-    }
-    r = init_session_tab(esysContext, shandle1, shandle2, shandle3);
-    return_if_error(r, "Initialize session resources");
+    return_state_if_error(r, _ESYS_STATE_INIT, "SAPI Prepare returned error.");
 
+    /* Calculate the cpHash Values */
+    r = init_session_tab(esysContext, shandle1, shandle2, shandle3);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Initialize session resources");
     iesys_compute_session_value(esysContext->session_tab[0],
                 &authNode->rsrc.name, &authNode->auth);
     iesys_compute_session_value(esysContext->session_tab[1], NULL, NULL);
-    r = iesys_gen_auths(esysContext, authNode, NULL, NULL, &auths);
-    return_if_error(r, "Error in computation of auth values");
+    iesys_compute_session_value(esysContext->session_tab[2], NULL, NULL);
 
+    /* Generate the auth values and set them in the SAPI command buffer */
+    r = iesys_gen_auths(esysContext, authNode, NULL, NULL, &auths);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Error in computation of auth values");
     esysContext->authsCount = auths.count;
     r = Tss2_Sys_SetCmdAuths(esysContext->sys, &auths);
-    if (r != TSS2_RC_SUCCESS) {
-        return r;
-    }
+    return_state_if_error(r, _ESYS_STATE_INIT, "SAPI error on SetCmdAuths");
 
+    /* Trigger execution and finish the async invocation */
     r = Tss2_Sys_ExecuteAsync(esysContext->sys);
-    return_if_error(r, "Finish (Execute Async)");
+    return_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Finish (Execute Async)");
 
     esysContext->state = _ESYS_STATE_SENT;
 
@@ -204,26 +209,34 @@
     ESYS_CONTEXT *esysContext)
 {
     LOG_TRACE("complete");
+    TSS2_RC r;
     if (esysContext == NULL) {
         LOG_ERROR("esyscontext is NULL.");
         return TSS2_ESYS_RC_BAD_REFERENCE;
     }
+
+    /* Check for correct sequence and set sequence to irregular for now */
     if (esysContext->state != _ESYS_STATE_SENT) {
         LOG_ERROR("Esys called in bad sequence.");
         return TSS2_ESYS_RC_BAD_SEQUENCE;
     }
-    TSS2_RC r;
+    esysContext->state = _ESYS_STATE_INTERNALERROR;
+
+    /*Receive the TPM response and handle resubmissions if necessary. */
     r = Tss2_Sys_ExecuteFinish(esysContext->sys, esysContext->timeout);
     if ((r & ~TSS2_RC_LAYER_MASK) == TSS2_BASE_RC_TRY_AGAIN) {
         LOG_DEBUG("A layer below returned TRY_AGAIN: %" PRIx32, r);
+        esysContext->state = _ESYS_STATE_SENT;
         return r;
     }
+    /* This block handle the resubmission of TPM commands given a certain set of
+     * TPM response codes. */
     if (r == TPM2_RC_RETRY || r == TPM2_RC_TESTING || r == TPM2_RC_YIELDED) {
         LOG_DEBUG("TPM returned RETRY, TESTING or YIELDED, which triggers a "
             "resubmission: %" PRIx32, r);
         if (esysContext->submissionCount >= _ESYS_MAX_SUBMISSIONS) {
-            LOG_WARNING("Maximum number of resubmissions has been reached.");
-            esysContext->state = _ESYS_STATE_ERRORRESPONSE;
+            LOG_WARNING("Maximum number of (re)submissions has been reached.");
+            esysContext->state = _ESYS_STATE_INIT;
             return r;
         }
         esysContext->state = _ESYS_STATE_RESUBMISSION;
@@ -234,33 +247,42 @@
                 esysContext->session_type[2],
                 esysContext->in.ClockRateAdjust.rateAdjust);
         if (r != TSS2_RC_SUCCESS) {
-            LOG_ERROR("Error attempting to resubmit");
+            LOG_WARNING("Error attempting to resubmit");
+            /* We do not set esysContext->state here but inherit the most recent
+             * state of the _async function. */
             return r;
         }
         r = TSS2_ESYS_RC_TRY_AGAIN;
+        LOG_DEBUG("Resubmission initiated and returning RC_TRY_AGAIN.");
         return r;
     }
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error finish (ExecuteFinish) ClockRateAdjust");
+    /* The following is the "regular error" handling. */
+    if (r != TSS2_RC_SUCCESS && (r & TSS2_RC_LAYER_MASK) == 0) {
+        LOG_WARNING("Received TPM Error");
+        esysContext->state = _ESYS_STATE_INIT;
+        return r;
+    } else if (r != TSS2_RC_SUCCESS) {
+        LOG_ERROR("Received a non-TPM Error");
+        esysContext->state = _ESYS_STATE_INTERNALERROR;
         return r;
     }
+
     /*
      * Now the verification of the response (hmac check) and if necessary the
-     * parameter decryption have to be done
+     * parameter decryption have to be done.
      */
     r = iesys_check_response(esysContext);
-    return_if_error(r, "Error: check response");
+    return_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Error: check response");
     /*
      * After the verification of the response we call the complete function
      * to deliver the result.
      */
     r = Tss2_Sys_ClockRateAdjust_Complete(esysContext->sys);
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error finish (ExecuteFinish) ClockRateAdjust: %" PRIx32, r);
-        esysContext->state = _ESYS_STATE_ERRORRESPONSE;
-        return r;;
-    }
-    esysContext->state = _ESYS_STATE_FINISHED;
+    return_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Received error from SAPI"
+                        " unmarshalling" );
+    esysContext->state = _ESYS_STATE_INIT;
+    LOG_DEBUG("context=%p",
+              esysContext);
 
-    return r;
+    return TSS2_RC_SUCCESS;
 }
diff --git a/src/tss2-esys/api/Esys_ClockSet.c b/src/tss2-esys/api/Esys_ClockSet.c
index 9223fa8..d2ebafe 100644
--- a/src/tss2-esys/api/Esys_ClockSet.c
+++ b/src/tss2-esys/api/Esys_ClockSet.c
@@ -142,6 +142,7 @@
     TSS2L_SYS_AUTH_COMMAND auths;
     RSRC_NODE_T *authNode;
 
+    /* Check context, sequence correctness and set state to error for now */
     if (esysContext == NULL) {
         LOG_ERROR("esyscontext is NULL.");
         return TSS2_ESYS_RC_BAD_REFERENCE;
@@ -149,38 +150,42 @@
     r = iesys_check_sequence_async(esysContext);
     if (r != TSS2_RC_SUCCESS)
         return r;
-    r = check_session_feasability(shandle1, shandle2, shandle3, 1);
-    return_if_error(r, "Check session usage");
+    esysContext->state = _ESYS_STATE_INTERNALERROR;
 
+    /* Check and store input parameters */
+    r = check_session_feasability(shandle1, shandle2, shandle3, 1);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Check session usage");
     store_input_parameters(esysContext, auth,
                 newTime);
+
+    /* Retrieve the metadata objects for provided handles */
     r = esys_GetResourceObject(esysContext, auth, &authNode);
-    if (r != TPM2_RC_SUCCESS)
-        return r;
+    return_state_if_error(r, _ESYS_STATE_INIT, "auth unknown.");
+
+    /* Initial invocation of SAPI to prepare the command buffer with parameters */
     r = Tss2_Sys_ClockSet_Prepare(esysContext->sys,
                 (authNode == NULL) ? TPM2_RH_NULL : authNode->rsrc.handle,
                 newTime);
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error async ClockSet");
-        return r;
-    }
-    r = init_session_tab(esysContext, shandle1, shandle2, shandle3);
-    return_if_error(r, "Initialize session resources");
+    return_state_if_error(r, _ESYS_STATE_INIT, "SAPI Prepare returned error.");
 
+    /* Calculate the cpHash Values */
+    r = init_session_tab(esysContext, shandle1, shandle2, shandle3);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Initialize session resources");
     iesys_compute_session_value(esysContext->session_tab[0],
                 &authNode->rsrc.name, &authNode->auth);
     iesys_compute_session_value(esysContext->session_tab[1], NULL, NULL);
-    r = iesys_gen_auths(esysContext, authNode, NULL, NULL, &auths);
-    return_if_error(r, "Error in computation of auth values");
+    iesys_compute_session_value(esysContext->session_tab[2], NULL, NULL);
 
+    /* Generate the auth values and set them in the SAPI command buffer */
+    r = iesys_gen_auths(esysContext, authNode, NULL, NULL, &auths);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Error in computation of auth values");
     esysContext->authsCount = auths.count;
     r = Tss2_Sys_SetCmdAuths(esysContext->sys, &auths);
-    if (r != TSS2_RC_SUCCESS) {
-        return r;
-    }
+    return_state_if_error(r, _ESYS_STATE_INIT, "SAPI error on SetCmdAuths");
 
+    /* Trigger execution and finish the async invocation */
     r = Tss2_Sys_ExecuteAsync(esysContext->sys);
-    return_if_error(r, "Finish (Execute Async)");
+    return_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Finish (Execute Async)");
 
     esysContext->state = _ESYS_STATE_SENT;
 
@@ -204,26 +209,34 @@
     ESYS_CONTEXT *esysContext)
 {
     LOG_TRACE("complete");
+    TSS2_RC r;
     if (esysContext == NULL) {
         LOG_ERROR("esyscontext is NULL.");
         return TSS2_ESYS_RC_BAD_REFERENCE;
     }
+
+    /* Check for correct sequence and set sequence to irregular for now */
     if (esysContext->state != _ESYS_STATE_SENT) {
         LOG_ERROR("Esys called in bad sequence.");
         return TSS2_ESYS_RC_BAD_SEQUENCE;
     }
-    TSS2_RC r;
+    esysContext->state = _ESYS_STATE_INTERNALERROR;
+
+    /*Receive the TPM response and handle resubmissions if necessary. */
     r = Tss2_Sys_ExecuteFinish(esysContext->sys, esysContext->timeout);
     if ((r & ~TSS2_RC_LAYER_MASK) == TSS2_BASE_RC_TRY_AGAIN) {
         LOG_DEBUG("A layer below returned TRY_AGAIN: %" PRIx32, r);
+        esysContext->state = _ESYS_STATE_SENT;
         return r;
     }
+    /* This block handle the resubmission of TPM commands given a certain set of
+     * TPM response codes. */
     if (r == TPM2_RC_RETRY || r == TPM2_RC_TESTING || r == TPM2_RC_YIELDED) {
         LOG_DEBUG("TPM returned RETRY, TESTING or YIELDED, which triggers a "
             "resubmission: %" PRIx32, r);
         if (esysContext->submissionCount >= _ESYS_MAX_SUBMISSIONS) {
-            LOG_WARNING("Maximum number of resubmissions has been reached.");
-            esysContext->state = _ESYS_STATE_ERRORRESPONSE;
+            LOG_WARNING("Maximum number of (re)submissions has been reached.");
+            esysContext->state = _ESYS_STATE_INIT;
             return r;
         }
         esysContext->state = _ESYS_STATE_RESUBMISSION;
@@ -234,33 +247,42 @@
                 esysContext->session_type[2],
                 esysContext->in.ClockSet.newTime);
         if (r != TSS2_RC_SUCCESS) {
-            LOG_ERROR("Error attempting to resubmit");
+            LOG_WARNING("Error attempting to resubmit");
+            /* We do not set esysContext->state here but inherit the most recent
+             * state of the _async function. */
             return r;
         }
         r = TSS2_ESYS_RC_TRY_AGAIN;
+        LOG_DEBUG("Resubmission initiated and returning RC_TRY_AGAIN.");
         return r;
     }
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error finish (ExecuteFinish) ClockSet");
+    /* The following is the "regular error" handling. */
+    if (r != TSS2_RC_SUCCESS && (r & TSS2_RC_LAYER_MASK) == 0) {
+        LOG_WARNING("Received TPM Error");
+        esysContext->state = _ESYS_STATE_INIT;
+        return r;
+    } else if (r != TSS2_RC_SUCCESS) {
+        LOG_ERROR("Received a non-TPM Error");
+        esysContext->state = _ESYS_STATE_INTERNALERROR;
         return r;
     }
+
     /*
      * Now the verification of the response (hmac check) and if necessary the
-     * parameter decryption have to be done
+     * parameter decryption have to be done.
      */
     r = iesys_check_response(esysContext);
-    return_if_error(r, "Error: check response");
+    return_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Error: check response");
     /*
      * After the verification of the response we call the complete function
      * to deliver the result.
      */
     r = Tss2_Sys_ClockSet_Complete(esysContext->sys);
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error finish (ExecuteFinish) ClockSet: %" PRIx32, r);
-        esysContext->state = _ESYS_STATE_ERRORRESPONSE;
-        return r;;
-    }
-    esysContext->state = _ESYS_STATE_FINISHED;
+    return_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Received error from SAPI"
+                        " unmarshalling" );
+    esysContext->state = _ESYS_STATE_INIT;
+    LOG_DEBUG("context=%p",
+              esysContext);
 
-    return r;
+    return TSS2_RC_SUCCESS;
 }
diff --git a/src/tss2-esys/api/Esys_Commit.c b/src/tss2-esys/api/Esys_Commit.c
index be02492..21eef8e 100644
--- a/src/tss2-esys/api/Esys_Commit.c
+++ b/src/tss2-esys/api/Esys_Commit.c
@@ -190,6 +190,7 @@
     TSS2L_SYS_AUTH_COMMAND auths;
     RSRC_NODE_T *signHandleNode;
 
+    /* Check context, sequence correctness and set state to error for now */
     if (esysContext == NULL) {
         LOG_ERROR("esyscontext is NULL.");
         return TSS2_ESYS_RC_BAD_REFERENCE;
@@ -197,43 +198,46 @@
     r = iesys_check_sequence_async(esysContext);
     if (r != TSS2_RC_SUCCESS)
         return r;
-    r = check_session_feasability(shandle1, shandle2, shandle3, 1);
-    return_if_error(r, "Check session usage");
+    esysContext->state = _ESYS_STATE_INTERNALERROR;
 
+    /* Check and store input parameters */
+    r = check_session_feasability(shandle1, shandle2, shandle3, 1);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Check session usage");
     store_input_parameters(esysContext, signHandle,
                 P1,
                 s2,
                 y2);
+
+    /* Retrieve the metadata objects for provided handles */
     r = esys_GetResourceObject(esysContext, signHandle, &signHandleNode);
-    if (r != TPM2_RC_SUCCESS)
-        return r;
+    return_state_if_error(r, _ESYS_STATE_INIT, "signHandle unknown.");
+
+    /* Initial invocation of SAPI to prepare the command buffer with parameters */
     r = Tss2_Sys_Commit_Prepare(esysContext->sys,
                 (signHandleNode == NULL) ? TPM2_RH_NULL : signHandleNode->rsrc.handle,
                 P1,
                 s2,
                 y2);
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error async Commit");
-        return r;
-    }
-    r = init_session_tab(esysContext, shandle1, shandle2, shandle3);
-    return_if_error(r, "Initialize session resources");
+    return_state_if_error(r, _ESYS_STATE_INIT, "SAPI Prepare returned error.");
 
+    /* Calculate the cpHash Values */
+    r = init_session_tab(esysContext, shandle1, shandle2, shandle3);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Initialize session resources");
     iesys_compute_session_value(esysContext->session_tab[0],
                 &signHandleNode->rsrc.name, &signHandleNode->auth);
     iesys_compute_session_value(esysContext->session_tab[1], NULL, NULL);
     iesys_compute_session_value(esysContext->session_tab[2], NULL, NULL);
-    r = iesys_gen_auths(esysContext, signHandleNode, NULL, NULL, &auths);
-    return_if_error(r, "Error in computation of auth values");
 
+    /* Generate the auth values and set them in the SAPI command buffer */
+    r = iesys_gen_auths(esysContext, signHandleNode, NULL, NULL, &auths);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Error in computation of auth values");
     esysContext->authsCount = auths.count;
     r = Tss2_Sys_SetCmdAuths(esysContext->sys, &auths);
-    if (r != TSS2_RC_SUCCESS) {
-        return r;
-    }
+    return_state_if_error(r, _ESYS_STATE_INIT, "SAPI error on SetCmdAuths");
 
+    /* Trigger execution and finish the async invocation */
     r = Tss2_Sys_ExecuteAsync(esysContext->sys);
-    return_if_error(r, "Finish (Execute Async)");
+    return_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Finish (Execute Async)");
 
     esysContext->state = _ESYS_STATE_SENT;
 
@@ -269,15 +273,20 @@
     UINT16 *counter)
 {
     LOG_TRACE("complete");
+    TSS2_RC r;
     if (esysContext == NULL) {
         LOG_ERROR("esyscontext is NULL.");
         return TSS2_ESYS_RC_BAD_REFERENCE;
     }
+
+    /* Check for correct sequence and set sequence to irregular for now */
     if (esysContext->state != _ESYS_STATE_SENT) {
         LOG_ERROR("Esys called in bad sequence.");
         return TSS2_ESYS_RC_BAD_SEQUENCE;
     }
-    TSS2_RC r;
+    esysContext->state = _ESYS_STATE_INTERNALERROR;
+
+    /* Allocate memory for response parameters */
     if (K != NULL) {
         *K = calloc(sizeof(TPM2B_ECC_POINT), 1);
         if (*K == NULL) {
@@ -296,17 +305,22 @@
             goto_error(r, TSS2_ESYS_RC_MEMORY, "Out of memory", error_cleanup);
         }
     }
+
+    /*Receive the TPM response and handle resubmissions if necessary. */
     r = Tss2_Sys_ExecuteFinish(esysContext->sys, esysContext->timeout);
     if ((r & ~TSS2_RC_LAYER_MASK) == TSS2_BASE_RC_TRY_AGAIN) {
         LOG_DEBUG("A layer below returned TRY_AGAIN: %" PRIx32, r);
+        esysContext->state = _ESYS_STATE_SENT;
         goto error_cleanup;
     }
+    /* This block handle the resubmission of TPM commands given a certain set of
+     * TPM response codes. */
     if (r == TPM2_RC_RETRY || r == TPM2_RC_TESTING || r == TPM2_RC_YIELDED) {
         LOG_DEBUG("TPM returned RETRY, TESTING or YIELDED, which triggers a "
             "resubmission: %" PRIx32, r);
         if (esysContext->submissionCount >= _ESYS_MAX_SUBMISSIONS) {
-            LOG_WARNING("Maximum number of resubmissions has been reached.");
-            esysContext->state = _ESYS_STATE_ERRORRESPONSE;
+            LOG_WARNING("Maximum number of (re)submissions has been reached.");
+            esysContext->state = _ESYS_STATE_INIT;
             goto error_cleanup;
         }
         esysContext->state = _ESYS_STATE_RESUBMISSION;
@@ -319,22 +333,32 @@
                 esysContext->in.Commit.s2,
                 esysContext->in.Commit.y2);
         if (r != TSS2_RC_SUCCESS) {
-            LOG_ERROR("Error attempting to resubmit");
+            LOG_WARNING("Error attempting to resubmit");
+            /* We do not set esysContext->state here but inherit the most recent
+             * state of the _async function. */
             goto error_cleanup;
         }
         r = TSS2_ESYS_RC_TRY_AGAIN;
+        LOG_DEBUG("Resubmission initiated and returning RC_TRY_AGAIN.");
         goto error_cleanup;
     }
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error finish (ExecuteFinish) Commit");
+    /* The following is the "regular error" handling. */
+    if (r != TSS2_RC_SUCCESS && (r & TSS2_RC_LAYER_MASK) == 0) {
+        LOG_WARNING("Received TPM Error");
+        esysContext->state = _ESYS_STATE_INIT;
+        goto error_cleanup;
+    } else if (r != TSS2_RC_SUCCESS) {
+        LOG_ERROR("Received a non-TPM Error");
+        esysContext->state = _ESYS_STATE_INTERNALERROR;
         goto error_cleanup;
     }
+
     /*
      * Now the verification of the response (hmac check) and if necessary the
-     * parameter decryption have to be done
+     * parameter decryption have to be done.
      */
     r = iesys_check_response(esysContext);
-    goto_if_error(r, "Error: check response",
+    goto_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Error: check response",
                       error_cleanup);
     /*
      * After the verification of the response we call the complete function
@@ -345,14 +369,15 @@
                 (L != NULL) ? *L : NULL,
                 (E != NULL) ? *E : NULL,
                 counter);
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error finish (ExecuteFinish) Commit: %" PRIx32, r);
-        esysContext->state = _ESYS_STATE_ERRORRESPONSE;
-        goto error_cleanup;;
-    }
-    esysContext->state = _ESYS_STATE_FINISHED;
+    goto_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Received error from SAPI"
+                        " unmarshalling" ,error_cleanup);
+    esysContext->state = _ESYS_STATE_INIT;
+    LOG_DEBUG("context=%p, K=%p, L=%p,"
+              "E=%p, counter=%p",
+              esysContext, K, L,
+              E, counter);
 
-    return r;
+    return TSS2_RC_SUCCESS;
 
 error_cleanup:
     if (K != NULL)
@@ -361,5 +386,6 @@
         SAFE_FREE(*L);
     if (E != NULL)
         SAFE_FREE(*E);
+
     return r;
 }
diff --git a/src/tss2-esys/api/Esys_ContextLoad.c b/src/tss2-esys/api/Esys_ContextLoad.c
index b106341..7fb2886 100644
--- a/src/tss2-esys/api/Esys_ContextLoad.c
+++ b/src/tss2-esys/api/Esys_ContextLoad.c
@@ -127,6 +127,7 @@
     IESYS_CONTEXT_DATA esyscontextData = {0};
     TPMS_CONTEXT tpmContext;
 
+    /* Check context, sequence correctness and set state to error for now */
     if (esysContext == NULL) {
         LOG_ERROR("esyscontext is NULL.");
         return TSS2_ESYS_RC_BAD_REFERENCE;
@@ -134,14 +135,19 @@
     r = iesys_check_sequence_async(esysContext);
     if (r != TSS2_RC_SUCCESS)
         return r;
-
+    esysContext->state = _ESYS_STATE_INTERNALERROR;
     store_input_parameters(esysContext,
                 context);
     size_t offset = 0;
 
-    /* ESYS Special Handling Code: The context was extended with metadata during
-       Esys_ContextSave. Here we extract the TPM-parts to pass then to the TPM.
-    */
+    /*
+     * ESYS Special Handling Code: The context was extended with metadata during
+     * Esys_ContextSave. Here we extract the TPM-parts to pass then to the TPM.
+     */
+    if (context == NULL) {
+        LOG_ERROR("context is NULL.");
+        return TSS2_ESYS_RC_BAD_REFERENCE;
+    }
     r = Tss2_MU_IESYS_CONTEXT_DATA_Unmarshal (&context->contextBlob.buffer[0],
                                               context->contextBlob.size,
                                               &offset, &esyscontextData);
@@ -160,14 +166,14 @@
        it is nowhere used beyond this point. */
     context = &tpmContext;
 
+
+    /* Initial invocation of SAPI to prepare the command buffer with parameters */
     r = Tss2_Sys_ContextLoad_Prepare(esysContext->sys,
                 context);
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error async ContextLoad");
-        return r;
-    }
+    return_state_if_error(r, _ESYS_STATE_INIT, "SAPI Prepare returned error.");
+    /* Trigger execution and finish the async invocation */
     r = Tss2_Sys_ExecuteAsync(esysContext->sys);
-    return_if_error(r, "Finish (Execute Async)");
+    return_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Finish (Execute Async)");
 
     esysContext->state = _ESYS_STATE_SENT;
 
@@ -193,18 +199,22 @@
     ESYS_TR *loadedHandle)
 {
     LOG_TRACE("complete");
+    TSS2_RC r;
     if (esysContext == NULL) {
         LOG_ERROR("esyscontext is NULL.");
         return TSS2_ESYS_RC_BAD_REFERENCE;
     }
+
+    /* Check for correct sequence and set sequence to irregular for now */
     if (esysContext->state != _ESYS_STATE_SENT) {
         LOG_ERROR("Esys called in bad sequence.");
         return TSS2_ESYS_RC_BAD_SEQUENCE;
     }
-    TSS2_RC r;
-    IESYS_RESOURCE *loadedHandleRsrc = NULL;
+    esysContext->state = _ESYS_STATE_INTERNALERROR;
     RSRC_NODE_T *loadedHandleNode = NULL;
 
+
+    /* Allocate memory for response parameters */
     if (loadedHandle == NULL) {
         LOG_ERROR("Handle loadedHandle may not be NULL");
         return TSS2_ESYS_RC_BAD_REFERENCE;
@@ -222,45 +232,59 @@
     goto_if_error(r, "while unmarshaling context ", error_cleanup);
 
     loadedHandleNode->rsrc = esyscontextData.esysMetadata.data;
+
+    /*Receive the TPM response and handle resubmissions if necessary. */
     r = Tss2_Sys_ExecuteFinish(esysContext->sys, esysContext->timeout);
     if ((r & ~TSS2_RC_LAYER_MASK) == TSS2_BASE_RC_TRY_AGAIN) {
         LOG_DEBUG("A layer below returned TRY_AGAIN: %" PRIx32, r);
+        esysContext->state = _ESYS_STATE_SENT;
         goto error_cleanup;
     }
+    /* This block handle the resubmission of TPM commands given a certain set of
+     * TPM response codes. */
     if (r == TPM2_RC_RETRY || r == TPM2_RC_TESTING || r == TPM2_RC_YIELDED) {
         LOG_DEBUG("TPM returned RETRY, TESTING or YIELDED, which triggers a "
             "resubmission: %" PRIx32, r);
         if (esysContext->submissionCount >= _ESYS_MAX_SUBMISSIONS) {
-            LOG_WARNING("Maximum number of resubmissions has been reached.");
-            esysContext->state = _ESYS_STATE_ERRORRESPONSE;
+            LOG_WARNING("Maximum number of (re)submissions has been reached.");
+            esysContext->state = _ESYS_STATE_INIT;
             goto error_cleanup;
         }
         esysContext->state = _ESYS_STATE_RESUBMISSION;
         r = Esys_ContextLoad_async(esysContext,
                 esysContext->in.ContextLoad.context);
         if (r != TSS2_RC_SUCCESS) {
-            LOG_ERROR("Error attempting to resubmit");
+            LOG_WARNING("Error attempting to resubmit");
+            /* We do not set esysContext->state here but inherit the most recent
+             * state of the _async function. */
             goto error_cleanup;
         }
         r = TSS2_ESYS_RC_TRY_AGAIN;
+        LOG_DEBUG("Resubmission initiated and returning RC_TRY_AGAIN.");
         goto error_cleanup;
     }
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error finish (ExecuteFinish) ContextLoad");
+    /* The following is the "regular error" handling. */
+    if (r != TSS2_RC_SUCCESS && (r & TSS2_RC_LAYER_MASK) == 0) {
+        LOG_WARNING("Received TPM Error");
+        esysContext->state = _ESYS_STATE_INIT;
+        goto error_cleanup;
+    } else if (r != TSS2_RC_SUCCESS) {
+        LOG_ERROR("Received a non-TPM Error");
+        esysContext->state = _ESYS_STATE_INTERNALERROR;
         goto error_cleanup;
     }
     r = Tss2_Sys_ContextLoad_Complete(esysContext->sys,
                 &loadedHandleNode->rsrc.handle);
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error finish (ExecuteFinish) ContextLoad: %" PRIx32, r);
-        esysContext->state = _ESYS_STATE_ERRORRESPONSE;
-        goto error_cleanup;;
-    }
-    esysContext->state = _ESYS_STATE_FINISHED;
+    goto_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Received error from SAPI"
+                        " unmarshalling" ,error_cleanup);
+    esysContext->state = _ESYS_STATE_INIT;
+    LOG_DEBUG("context=%p, loadedHandle=%p",
+              esysContext, loadedHandle);
 
-    return r;
+    return TSS2_RC_SUCCESS;
 
 error_cleanup:
     Esys_TR_Close(esysContext, loadedHandle);
+
     return r;
 }
diff --git a/src/tss2-esys/api/Esys_ContextSave.c b/src/tss2-esys/api/Esys_ContextSave.c
index 0b61344..cb1e8eb 100644
--- a/src/tss2-esys/api/Esys_ContextSave.c
+++ b/src/tss2-esys/api/Esys_ContextSave.c
@@ -123,6 +123,7 @@
     TSS2_RC r;
     RSRC_NODE_T *saveHandleNode;
 
+    /* Check context, sequence correctness and set state to error for now */
     if (esysContext == NULL) {
         LOG_ERROR("esyscontext is NULL.");
         return TSS2_ESYS_RC_BAD_REFERENCE;
@@ -130,19 +131,20 @@
     r = iesys_check_sequence_async(esysContext);
     if (r != TSS2_RC_SUCCESS)
         return r;
-
+    esysContext->state = _ESYS_STATE_INTERNALERROR;
     store_input_parameters(esysContext, saveHandle);
+
+    /* Retrieve the metadata objects for provided handles */
     r = esys_GetResourceObject(esysContext, saveHandle, &saveHandleNode);
-    if (r != TPM2_RC_SUCCESS)
-        return r;
+    return_state_if_error(r, _ESYS_STATE_INIT, "saveHandle unknown.");
+
+    /* Initial invocation of SAPI to prepare the command buffer with parameters */
     r = Tss2_Sys_ContextSave_Prepare(esysContext->sys,
                 (saveHandleNode == NULL) ? TPM2_RH_NULL : saveHandleNode->rsrc.handle);
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error async ContextSave");
-        return r;
-    }
+    return_state_if_error(r, _ESYS_STATE_INIT, "SAPI Prepare returned error.");
+    /* Trigger execution and finish the async invocation */
     r = Tss2_Sys_ExecuteAsync(esysContext->sys);
-    return_if_error(r, "Finish (Execute Async)");
+    return_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Finish (Execute Async)");
 
     esysContext->state = _ESYS_STATE_SENT;
 
@@ -170,54 +172,71 @@
 {
     TPMS_CONTEXT *lcontext = NULL;
     LOG_TRACE("complete");
+    TSS2_RC r;
     if (esysContext == NULL) {
         LOG_ERROR("esyscontext is NULL.");
         return TSS2_ESYS_RC_BAD_REFERENCE;
     }
+
+    /* Check for correct sequence and set sequence to irregular for now */
     if (esysContext->state != _ESYS_STATE_SENT) {
         LOG_ERROR("Esys called in bad sequence.");
         return TSS2_ESYS_RC_BAD_SEQUENCE;
     }
-    TSS2_RC r;
+    esysContext->state = _ESYS_STATE_INTERNALERROR;
+
+    /* Allocate memory for response parameters */
     lcontext = calloc(sizeof(TPMS_CONTEXT), 1);
     if (lcontext == NULL) {
         return_error(TSS2_ESYS_RC_MEMORY, "Out of memory");
     }
+
+    /*Receive the TPM response and handle resubmissions if necessary. */
     r = Tss2_Sys_ExecuteFinish(esysContext->sys, esysContext->timeout);
     if ((r & ~TSS2_RC_LAYER_MASK) == TSS2_BASE_RC_TRY_AGAIN) {
         LOG_DEBUG("A layer below returned TRY_AGAIN: %" PRIx32, r);
+        esysContext->state = _ESYS_STATE_SENT;
         goto error_cleanup;
     }
+    /* This block handle the resubmission of TPM commands given a certain set of
+     * TPM response codes. */
     if (r == TPM2_RC_RETRY || r == TPM2_RC_TESTING || r == TPM2_RC_YIELDED) {
         LOG_DEBUG("TPM returned RETRY, TESTING or YIELDED, which triggers a "
             "resubmission: %" PRIx32, r);
         if (esysContext->submissionCount >= _ESYS_MAX_SUBMISSIONS) {
-            LOG_WARNING("Maximum number of resubmissions has been reached.");
-            esysContext->state = _ESYS_STATE_ERRORRESPONSE;
+            LOG_WARNING("Maximum number of (re)submissions has been reached.");
+            esysContext->state = _ESYS_STATE_INIT;
             goto error_cleanup;
         }
         esysContext->state = _ESYS_STATE_RESUBMISSION;
         r = Esys_ContextSave_async(esysContext,
                 esysContext->in.ContextSave.saveHandle);
         if (r != TSS2_RC_SUCCESS) {
-            LOG_ERROR("Error attempting to resubmit");
+            LOG_WARNING("Error attempting to resubmit");
+            /* We do not set esysContext->state here but inherit the most recent
+             * state of the _async function. */
             goto error_cleanup;
         }
         r = TSS2_ESYS_RC_TRY_AGAIN;
+        LOG_DEBUG("Resubmission initiated and returning RC_TRY_AGAIN.");
         goto error_cleanup;
     }
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error finish (ExecuteFinish) ContextSave");
+    /* The following is the "regular error" handling. */
+    if (r != TSS2_RC_SUCCESS && (r & TSS2_RC_LAYER_MASK) == 0) {
+        LOG_WARNING("Received TPM Error");
+        esysContext->state = _ESYS_STATE_INIT;
+        goto error_cleanup;
+    } else if (r != TSS2_RC_SUCCESS) {
+        LOG_ERROR("Received a non-TPM Error");
+        esysContext->state = _ESYS_STATE_INTERNALERROR;
         goto error_cleanup;
     }
     r = Tss2_Sys_ContextSave_Complete(esysContext->sys,
                 lcontext);
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error finish (ExecuteFinish) ContextSave: %" PRIx32, r);
-        esysContext->state = _ESYS_STATE_ERRORRESPONSE;
-        goto error_cleanup;;
-    }
+    goto_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Received error from SAPI"
+                        " unmarshalling" ,error_cleanup);
 
+    /* ESYS Special Handling Code: Extend the  context with metadata of the object */
     IESYS_CONTEXT_DATA esyscontextData;
     RSRC_NODE_T *esys_object;
     size_t offset = 0;
@@ -251,11 +270,14 @@
     else
         SAFE_FREE(lcontext);
 
-    esysContext->state = _ESYS_STATE_FINISHED;
+    esysContext->state = _ESYS_STATE_INIT;
+    LOG_DEBUG("context=%p, context=%p",
+              esysContext, context);
 
-    return r;
+    return TSS2_RC_SUCCESS;
 
 error_cleanup:
     SAFE_FREE(lcontext);
+
     return r;
 }
diff --git a/src/tss2-esys/api/Esys_Create.c b/src/tss2-esys/api/Esys_Create.c
index 16872f9..a8dbe53 100644
--- a/src/tss2-esys/api/Esys_Create.c
+++ b/src/tss2-esys/api/Esys_Create.c
@@ -207,6 +207,7 @@
     TSS2L_SYS_AUTH_COMMAND auths;
     RSRC_NODE_T *parentHandleNode;
 
+    /* Check context, sequence correctness and set state to error for now */
     if (esysContext == NULL) {
         LOG_ERROR("esyscontext is NULL.");
         return TSS2_ESYS_RC_BAD_REFERENCE;
@@ -214,45 +215,48 @@
     r = iesys_check_sequence_async(esysContext);
     if (r != TSS2_RC_SUCCESS)
         return r;
-    r = check_session_feasability(shandle1, shandle2, shandle3, 1);
-    return_if_error(r, "Check session usage");
+    esysContext->state = _ESYS_STATE_INTERNALERROR;
 
+    /* Check and store input parameters */
+    r = check_session_feasability(shandle1, shandle2, shandle3, 1);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Check session usage");
     store_input_parameters(esysContext, parentHandle,
                 inSensitive,
                 inPublic,
                 outsideInfo,
                 creationPCR);
+
+    /* Retrieve the metadata objects for provided handles */
     r = esys_GetResourceObject(esysContext, parentHandle, &parentHandleNode);
-    if (r != TPM2_RC_SUCCESS)
-        return r;
+    return_state_if_error(r, _ESYS_STATE_INIT, "parentHandle unknown.");
+
+    /* Initial invocation of SAPI to prepare the command buffer with parameters */
     r = Tss2_Sys_Create_Prepare(esysContext->sys,
                 (parentHandleNode == NULL) ? TPM2_RH_NULL : parentHandleNode->rsrc.handle,
                 inSensitive,
                 inPublic,
                 outsideInfo,
                 creationPCR);
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error async Create");
-        return r;
-    }
-    r = init_session_tab(esysContext, shandle1, shandle2, shandle3);
-    return_if_error(r, "Initialize session resources");
+    return_state_if_error(r, _ESYS_STATE_INIT, "SAPI Prepare returned error.");
 
+    /* Calculate the cpHash Values */
+    r = init_session_tab(esysContext, shandle1, shandle2, shandle3);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Initialize session resources");
     iesys_compute_session_value(esysContext->session_tab[0],
                 &parentHandleNode->rsrc.name, &parentHandleNode->auth);
     iesys_compute_session_value(esysContext->session_tab[1], NULL, NULL);
     iesys_compute_session_value(esysContext->session_tab[2], NULL, NULL);
-    r = iesys_gen_auths(esysContext, parentHandleNode, NULL, NULL, &auths);
-    return_if_error(r, "Error in computation of auth values");
 
+    /* Generate the auth values and set them in the SAPI command buffer */
+    r = iesys_gen_auths(esysContext, parentHandleNode, NULL, NULL, &auths);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Error in computation of auth values");
     esysContext->authsCount = auths.count;
     r = Tss2_Sys_SetCmdAuths(esysContext->sys, &auths);
-    if (r != TSS2_RC_SUCCESS) {
-        return r;
-    }
+    return_state_if_error(r, _ESYS_STATE_INIT, "SAPI error on SetCmdAuths");
 
+    /* Trigger execution and finish the async invocation */
     r = Tss2_Sys_ExecuteAsync(esysContext->sys);
-    return_if_error(r, "Finish (Execute Async)");
+    return_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Finish (Execute Async)");
 
     esysContext->state = _ESYS_STATE_SENT;
 
@@ -291,15 +295,20 @@
     TPMT_TK_CREATION **creationTicket)
 {
     LOG_TRACE("complete");
+    TSS2_RC r;
     if (esysContext == NULL) {
         LOG_ERROR("esyscontext is NULL.");
         return TSS2_ESYS_RC_BAD_REFERENCE;
     }
+
+    /* Check for correct sequence and set sequence to irregular for now */
     if (esysContext->state != _ESYS_STATE_SENT) {
         LOG_ERROR("Esys called in bad sequence.");
         return TSS2_ESYS_RC_BAD_SEQUENCE;
     }
-    TSS2_RC r;
+    esysContext->state = _ESYS_STATE_INTERNALERROR;
+
+    /* Allocate memory for response parameters */
     if (outPrivate != NULL) {
         *outPrivate = calloc(sizeof(TPM2B_PRIVATE), 1);
         if (*outPrivate == NULL) {
@@ -330,17 +339,22 @@
             goto_error(r, TSS2_ESYS_RC_MEMORY, "Out of memory", error_cleanup);
         }
     }
+
+    /*Receive the TPM response and handle resubmissions if necessary. */
     r = Tss2_Sys_ExecuteFinish(esysContext->sys, esysContext->timeout);
     if ((r & ~TSS2_RC_LAYER_MASK) == TSS2_BASE_RC_TRY_AGAIN) {
         LOG_DEBUG("A layer below returned TRY_AGAIN: %" PRIx32, r);
+        esysContext->state = _ESYS_STATE_SENT;
         goto error_cleanup;
     }
+    /* This block handle the resubmission of TPM commands given a certain set of
+     * TPM response codes. */
     if (r == TPM2_RC_RETRY || r == TPM2_RC_TESTING || r == TPM2_RC_YIELDED) {
         LOG_DEBUG("TPM returned RETRY, TESTING or YIELDED, which triggers a "
             "resubmission: %" PRIx32, r);
         if (esysContext->submissionCount >= _ESYS_MAX_SUBMISSIONS) {
-            LOG_WARNING("Maximum number of resubmissions has been reached.");
-            esysContext->state = _ESYS_STATE_ERRORRESPONSE;
+            LOG_WARNING("Maximum number of (re)submissions has been reached.");
+            esysContext->state = _ESYS_STATE_INIT;
             goto error_cleanup;
         }
         esysContext->state = _ESYS_STATE_RESUBMISSION;
@@ -354,22 +368,32 @@
                 esysContext->in.Create.outsideInfo,
                 esysContext->in.Create.creationPCR);
         if (r != TSS2_RC_SUCCESS) {
-            LOG_ERROR("Error attempting to resubmit");
+            LOG_WARNING("Error attempting to resubmit");
+            /* We do not set esysContext->state here but inherit the most recent
+             * state of the _async function. */
             goto error_cleanup;
         }
         r = TSS2_ESYS_RC_TRY_AGAIN;
+        LOG_DEBUG("Resubmission initiated and returning RC_TRY_AGAIN.");
         goto error_cleanup;
     }
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error finish (ExecuteFinish) Create");
+    /* The following is the "regular error" handling. */
+    if (r != TSS2_RC_SUCCESS && (r & TSS2_RC_LAYER_MASK) == 0) {
+        LOG_WARNING("Received TPM Error");
+        esysContext->state = _ESYS_STATE_INIT;
+        goto error_cleanup;
+    } else if (r != TSS2_RC_SUCCESS) {
+        LOG_ERROR("Received a non-TPM Error");
+        esysContext->state = _ESYS_STATE_INTERNALERROR;
         goto error_cleanup;
     }
+
     /*
      * Now the verification of the response (hmac check) and if necessary the
-     * parameter decryption have to be done
+     * parameter decryption have to be done.
      */
     r = iesys_check_response(esysContext);
-    goto_if_error(r, "Error: check response",
+    goto_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Error: check response",
                       error_cleanup);
     /*
      * After the verification of the response we call the complete function
@@ -381,14 +405,15 @@
                 (creationData != NULL) ? *creationData : NULL,
                 (creationHash != NULL) ? *creationHash : NULL,
                 (creationTicket != NULL) ? *creationTicket : NULL);
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error finish (ExecuteFinish) Create: %" PRIx32, r);
-        esysContext->state = _ESYS_STATE_ERRORRESPONSE;
-        goto error_cleanup;;
-    }
-    esysContext->state = _ESYS_STATE_FINISHED;
+    goto_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Received error from SAPI"
+                        " unmarshalling" ,error_cleanup);
+    esysContext->state = _ESYS_STATE_INIT;
+    LOG_DEBUG("context=%p, outPrivate=%p, outPublic=%p,"
+              "creationData=%p, creationHash=%p, creationTicket=%p",
+              esysContext, outPrivate, outPublic,
+              creationData, creationHash, creationTicket);
 
-    return r;
+    return TSS2_RC_SUCCESS;
 
 error_cleanup:
     if (outPrivate != NULL)
@@ -401,5 +426,6 @@
         SAFE_FREE(*creationHash);
     if (creationTicket != NULL)
         SAFE_FREE(*creationTicket);
+
     return r;
 }
diff --git a/src/tss2-esys/api/Esys_CreateLoaded.c b/src/tss2-esys/api/Esys_CreateLoaded.c
index 500d20a..3d4e408 100644
--- a/src/tss2-esys/api/Esys_CreateLoaded.c
+++ b/src/tss2-esys/api/Esys_CreateLoaded.c
@@ -172,6 +172,7 @@
     TSS2L_SYS_AUTH_COMMAND auths;
     RSRC_NODE_T *parentHandleNode;
 
+    /* Check context, sequence correctness and set state to error for now */
     if (esysContext == NULL) {
         LOG_ERROR("esyscontext is NULL.");
         return TSS2_ESYS_RC_BAD_REFERENCE;
@@ -179,41 +180,44 @@
     r = iesys_check_sequence_async(esysContext);
     if (r != TSS2_RC_SUCCESS)
         return r;
-    r = check_session_feasability(shandle1, shandle2, shandle3, 1);
-    return_if_error(r, "Check session usage");
+    esysContext->state = _ESYS_STATE_INTERNALERROR;
 
+    /* Check and store input parameters */
+    r = check_session_feasability(shandle1, shandle2, shandle3, 1);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Check session usage");
     store_input_parameters(esysContext, parentHandle,
                 inSensitive,
                 inPublic);
+
+    /* Retrieve the metadata objects for provided handles */
     r = esys_GetResourceObject(esysContext, parentHandle, &parentHandleNode);
-    if (r != TPM2_RC_SUCCESS)
-        return r;
+    return_state_if_error(r, _ESYS_STATE_INIT, "parentHandle unknown.");
+
+    /* Initial invocation of SAPI to prepare the command buffer with parameters */
     r = Tss2_Sys_CreateLoaded_Prepare(esysContext->sys,
                 (parentHandleNode == NULL) ? TPM2_RH_NULL : parentHandleNode->rsrc.handle,
                 inSensitive,
                 inPublic);
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error async CreateLoaded");
-        return r;
-    }
-    r = init_session_tab(esysContext, shandle1, shandle2, shandle3);
-    return_if_error(r, "Initialize session resources");
+    return_state_if_error(r, _ESYS_STATE_INIT, "SAPI Prepare returned error.");
 
+    /* Calculate the cpHash Values */
+    r = init_session_tab(esysContext, shandle1, shandle2, shandle3);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Initialize session resources");
     iesys_compute_session_value(esysContext->session_tab[0],
                 &parentHandleNode->rsrc.name, &parentHandleNode->auth);
     iesys_compute_session_value(esysContext->session_tab[1], NULL, NULL);
     iesys_compute_session_value(esysContext->session_tab[2], NULL, NULL);
-    r = iesys_gen_auths(esysContext, parentHandleNode, NULL, NULL, &auths);
-    return_if_error(r, "Error in computation of auth values");
 
+    /* Generate the auth values and set them in the SAPI command buffer */
+    r = iesys_gen_auths(esysContext, parentHandleNode, NULL, NULL, &auths);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Error in computation of auth values");
     esysContext->authsCount = auths.count;
     r = Tss2_Sys_SetCmdAuths(esysContext->sys, &auths);
-    if (r != TSS2_RC_SUCCESS) {
-        return r;
-    }
+    return_state_if_error(r, _ESYS_STATE_INIT, "SAPI error on SetCmdAuths");
 
+    /* Trigger execution and finish the async invocation */
     r = Tss2_Sys_ExecuteAsync(esysContext->sys);
-    return_if_error(r, "Finish (Execute Async)");
+    return_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Finish (Execute Async)");
 
     esysContext->state = _ESYS_STATE_SENT;
 
@@ -246,19 +250,23 @@
 {
     TPM2B_PUBLIC *loutPublic = NULL;
     LOG_TRACE("complete");
+    TSS2_RC r;
     if (esysContext == NULL) {
         LOG_ERROR("esyscontext is NULL.");
         return TSS2_ESYS_RC_BAD_REFERENCE;
     }
+
+    /* Check for correct sequence and set sequence to irregular for now */
     if (esysContext->state != _ESYS_STATE_SENT) {
         LOG_ERROR("Esys called in bad sequence.");
         return TSS2_ESYS_RC_BAD_SEQUENCE;
     }
-    TSS2_RC r;
+    esysContext->state = _ESYS_STATE_INTERNALERROR;
     TPM2B_NAME name;
-    IESYS_RESOURCE *objectHandleRsrc = NULL;
     RSRC_NODE_T *objectHandleNode = NULL;
 
+
+    /* Allocate memory for response parameters */
     if (objectHandle == NULL) {
         LOG_ERROR("Handle objectHandle may not be NULL");
         return TSS2_ESYS_RC_BAD_REFERENCE;
@@ -278,19 +286,30 @@
     if (loutPublic == NULL) {
         goto_error(r, TSS2_ESYS_RC_MEMORY, "Out of memory", error_cleanup);
     }
+
+    /* Update the meta data of the ESYS_TR object */
     objectHandleNode->rsrc.rsrcType = IESYSC_KEY_RSRC;
-    objectHandleNode->rsrc.misc.rsrc_key_pub = *esysContext->in.Load.inPublic;
+    size_t offset = 0;
+    r = Tss2_MU_TPMT_PUBLIC_Unmarshal(&esysContext->in.CreateLoaded.inPublic->buffer[0],
+                                      sizeof(TPMT_PUBLIC), &offset ,
+                                      &objectHandleNode->rsrc.misc.rsrc_key_pub.publicArea);
+    goto_if_error(r, "Unmarshal TPMT_PUBULIC", error_cleanup);
+
+    /*Receive the TPM response and handle resubmissions if necessary. */
     r = Tss2_Sys_ExecuteFinish(esysContext->sys, esysContext->timeout);
     if ((r & ~TSS2_RC_LAYER_MASK) == TSS2_BASE_RC_TRY_AGAIN) {
         LOG_DEBUG("A layer below returned TRY_AGAIN: %" PRIx32, r);
+        esysContext->state = _ESYS_STATE_SENT;
         goto error_cleanup;
     }
+    /* This block handle the resubmission of TPM commands given a certain set of
+     * TPM response codes. */
     if (r == TPM2_RC_RETRY || r == TPM2_RC_TESTING || r == TPM2_RC_YIELDED) {
         LOG_DEBUG("TPM returned RETRY, TESTING or YIELDED, which triggers a "
             "resubmission: %" PRIx32, r);
         if (esysContext->submissionCount >= _ESYS_MAX_SUBMISSIONS) {
-            LOG_WARNING("Maximum number of resubmissions has been reached.");
-            esysContext->state = _ESYS_STATE_ERRORRESPONSE;
+            LOG_WARNING("Maximum number of (re)submissions has been reached.");
+            esysContext->state = _ESYS_STATE_INIT;
             goto error_cleanup;
         }
         esysContext->state = _ESYS_STATE_RESUBMISSION;
@@ -302,22 +321,32 @@
                 esysContext->in.CreateLoaded.inSensitive,
                 esysContext->in.CreateLoaded.inPublic);
         if (r != TSS2_RC_SUCCESS) {
-            LOG_ERROR("Error attempting to resubmit");
+            LOG_WARNING("Error attempting to resubmit");
+            /* We do not set esysContext->state here but inherit the most recent
+             * state of the _async function. */
             goto error_cleanup;
         }
         r = TSS2_ESYS_RC_TRY_AGAIN;
+        LOG_DEBUG("Resubmission initiated and returning RC_TRY_AGAIN.");
         goto error_cleanup;
     }
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error finish (ExecuteFinish) CreateLoaded");
+    /* The following is the "regular error" handling. */
+    if (r != TSS2_RC_SUCCESS && (r & TSS2_RC_LAYER_MASK) == 0) {
+        LOG_WARNING("Received TPM Error");
+        esysContext->state = _ESYS_STATE_INIT;
+        goto error_cleanup;
+    } else if (r != TSS2_RC_SUCCESS) {
+        LOG_ERROR("Received a non-TPM Error");
+        esysContext->state = _ESYS_STATE_INTERNALERROR;
         goto error_cleanup;
     }
+
     /*
      * Now the verification of the response (hmac check) and if necessary the
-     * parameter decryption have to be done
+     * parameter decryption have to be done.
      */
     r = iesys_check_response(esysContext);
-    goto_if_error(r, "Error: check response",
+    goto_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Error: check response",
                       error_cleanup);
     /*
      * After the verification of the response we call the complete function
@@ -328,16 +357,15 @@
                 (outPrivate != NULL) ? *outPrivate : NULL,
                 loutPublic,
                 &name);
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error finish (ExecuteFinish) CreateLoaded: %" PRIx32, r);
-        esysContext->state = _ESYS_STATE_ERRORRESPONSE;
-        goto error_cleanup;;
-    }
+    goto_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Received error from SAPI"
+                        " unmarshalling" ,error_cleanup);
 
+    /* Check name and outPublic for consistency */
     if (!iesys_compare_name(loutPublic, &name))
         goto_error(r, TSS2_ESYS_RC_MALFORMED_RESPONSE,
             "in Public name not equal name in response", error_cleanup);
 
+    /* Update the meta data of the ESYS_TR object */
     objectHandleNode->rsrc.name = name;
     objectHandleNode->auth = esysContext->in.CreateLoaded.inSensitive->sensitive.userAuth;
     if (outPublic != NULL)
@@ -345,14 +373,19 @@
     else
         SAFE_FREE(loutPublic);
 
-    esysContext->state = _ESYS_STATE_FINISHED;
+    esysContext->state = _ESYS_STATE_INIT;
+    LOG_DEBUG("context=%p, objectHandle=%p, outPrivate=%p,"
+              "outPublic=%p",
+              esysContext, objectHandle, outPrivate,
+              outPublic);
 
-    return r;
+    return TSS2_RC_SUCCESS;
 
 error_cleanup:
     Esys_TR_Close(esysContext, objectHandle);
     if (outPrivate != NULL)
         SAFE_FREE(*outPrivate);
     SAFE_FREE(loutPublic);
+
     return r;
 }
diff --git a/src/tss2-esys/api/Esys_CreatePrimary.c b/src/tss2-esys/api/Esys_CreatePrimary.c
index 58aef17..c7397f7 100644
--- a/src/tss2-esys/api/Esys_CreatePrimary.c
+++ b/src/tss2-esys/api/Esys_CreatePrimary.c
@@ -206,6 +206,7 @@
     TSS2L_SYS_AUTH_COMMAND auths;
     RSRC_NODE_T *primaryHandleNode;
 
+    /* Check context, sequence correctness and set state to error for now */
     if (esysContext == NULL) {
         LOG_ERROR("esyscontext is NULL.");
         return TSS2_ESYS_RC_BAD_REFERENCE;
@@ -213,45 +214,48 @@
     r = iesys_check_sequence_async(esysContext);
     if (r != TSS2_RC_SUCCESS)
         return r;
-    r = check_session_feasability(shandle1, shandle2, shandle3, 1);
-    return_if_error(r, "Check session usage");
+    esysContext->state = _ESYS_STATE_INTERNALERROR;
 
+    /* Check and store input parameters */
+    r = check_session_feasability(shandle1, shandle2, shandle3, 1);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Check session usage");
     store_input_parameters(esysContext, primaryHandle,
                 inSensitive,
                 inPublic,
                 outsideInfo,
                 creationPCR);
+
+    /* Retrieve the metadata objects for provided handles */
     r = esys_GetResourceObject(esysContext, primaryHandle, &primaryHandleNode);
-    if (r != TPM2_RC_SUCCESS)
-        return r;
+    return_state_if_error(r, _ESYS_STATE_INIT, "primaryHandle unknown.");
+
+    /* Initial invocation of SAPI to prepare the command buffer with parameters */
     r = Tss2_Sys_CreatePrimary_Prepare(esysContext->sys,
                 (primaryHandleNode == NULL) ? TPM2_RH_NULL : primaryHandleNode->rsrc.handle,
                 inSensitive,
                 inPublic,
                 outsideInfo,
                 creationPCR);
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error async CreatePrimary");
-        return r;
-    }
-    r = init_session_tab(esysContext, shandle1, shandle2, shandle3);
-    return_if_error(r, "Initialize session resources");
+    return_state_if_error(r, _ESYS_STATE_INIT, "SAPI Prepare returned error.");
 
+    /* Calculate the cpHash Values */
+    r = init_session_tab(esysContext, shandle1, shandle2, shandle3);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Initialize session resources");
     iesys_compute_session_value(esysContext->session_tab[0],
                 &primaryHandleNode->rsrc.name, &primaryHandleNode->auth);
     iesys_compute_session_value(esysContext->session_tab[1], NULL, NULL);
     iesys_compute_session_value(esysContext->session_tab[2], NULL, NULL);
-    r = iesys_gen_auths(esysContext, primaryHandleNode, NULL, NULL, &auths);
-    return_if_error(r, "Error in computation of auth values");
 
+    /* Generate the auth values and set them in the SAPI command buffer */
+    r = iesys_gen_auths(esysContext, primaryHandleNode, NULL, NULL, &auths);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Error in computation of auth values");
     esysContext->authsCount = auths.count;
     r = Tss2_Sys_SetCmdAuths(esysContext->sys, &auths);
-    if (r != TSS2_RC_SUCCESS) {
-        return r;
-    }
+    return_state_if_error(r, _ESYS_STATE_INIT, "SAPI error on SetCmdAuths");
 
+    /* Trigger execution and finish the async invocation */
     r = Tss2_Sys_ExecuteAsync(esysContext->sys);
-    return_if_error(r, "Finish (Execute Async)");
+    return_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Finish (Execute Async)");
 
     esysContext->state = _ESYS_STATE_SENT;
 
@@ -290,19 +294,23 @@
 {
     TPM2B_PUBLIC *loutPublic = NULL;
     LOG_TRACE("complete");
+    TSS2_RC r;
     if (esysContext == NULL) {
         LOG_ERROR("esyscontext is NULL.");
         return TSS2_ESYS_RC_BAD_REFERENCE;
     }
+
+    /* Check for correct sequence and set sequence to irregular for now */
     if (esysContext->state != _ESYS_STATE_SENT) {
         LOG_ERROR("Esys called in bad sequence.");
         return TSS2_ESYS_RC_BAD_SEQUENCE;
     }
-    TSS2_RC r;
+    esysContext->state = _ESYS_STATE_INTERNALERROR;
     TPM2B_NAME name;
-    IESYS_RESOURCE *objectHandleRsrc = NULL;
     RSRC_NODE_T *objectHandleNode = NULL;
 
+
+    /* Allocate memory for response parameters */
     if (objectHandle == NULL) {
         LOG_ERROR("Handle objectHandle may not be NULL");
         return TSS2_ESYS_RC_BAD_REFERENCE;
@@ -334,17 +342,22 @@
             goto_error(r, TSS2_ESYS_RC_MEMORY, "Out of memory", error_cleanup);
         }
     }
+
+    /*Receive the TPM response and handle resubmissions if necessary. */
     r = Tss2_Sys_ExecuteFinish(esysContext->sys, esysContext->timeout);
     if ((r & ~TSS2_RC_LAYER_MASK) == TSS2_BASE_RC_TRY_AGAIN) {
         LOG_DEBUG("A layer below returned TRY_AGAIN: %" PRIx32, r);
+        esysContext->state = _ESYS_STATE_SENT;
         goto error_cleanup;
     }
+    /* This block handle the resubmission of TPM commands given a certain set of
+     * TPM response codes. */
     if (r == TPM2_RC_RETRY || r == TPM2_RC_TESTING || r == TPM2_RC_YIELDED) {
         LOG_DEBUG("TPM returned RETRY, TESTING or YIELDED, which triggers a "
             "resubmission: %" PRIx32, r);
         if (esysContext->submissionCount >= _ESYS_MAX_SUBMISSIONS) {
-            LOG_WARNING("Maximum number of resubmissions has been reached.");
-            esysContext->state = _ESYS_STATE_ERRORRESPONSE;
+            LOG_WARNING("Maximum number of (re)submissions has been reached.");
+            esysContext->state = _ESYS_STATE_INIT;
             goto error_cleanup;
         }
         esysContext->state = _ESYS_STATE_RESUBMISSION;
@@ -358,22 +371,32 @@
                 esysContext->in.CreatePrimary.outsideInfo,
                 esysContext->in.CreatePrimary.creationPCR);
         if (r != TSS2_RC_SUCCESS) {
-            LOG_ERROR("Error attempting to resubmit");
+            LOG_WARNING("Error attempting to resubmit");
+            /* We do not set esysContext->state here but inherit the most recent
+             * state of the _async function. */
             goto error_cleanup;
         }
         r = TSS2_ESYS_RC_TRY_AGAIN;
+        LOG_DEBUG("Resubmission initiated and returning RC_TRY_AGAIN.");
         goto error_cleanup;
     }
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error finish (ExecuteFinish) CreatePrimary");
+    /* The following is the "regular error" handling. */
+    if (r != TSS2_RC_SUCCESS && (r & TSS2_RC_LAYER_MASK) == 0) {
+        LOG_WARNING("Received TPM Error");
+        esysContext->state = _ESYS_STATE_INIT;
+        goto error_cleanup;
+    } else if (r != TSS2_RC_SUCCESS) {
+        LOG_ERROR("Received a non-TPM Error");
+        esysContext->state = _ESYS_STATE_INTERNALERROR;
         goto error_cleanup;
     }
+
     /*
      * Now the verification of the response (hmac check) and if necessary the
-     * parameter decryption have to be done
+     * parameter decryption have to be done.
      */
     r = iesys_check_response(esysContext);
-    goto_if_error(r, "Error: check response",
+    goto_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Error: check response",
                       error_cleanup);
     /*
      * After the verification of the response we call the complete function
@@ -386,16 +409,15 @@
                 (creationHash != NULL) ? *creationHash : NULL,
                 (creationTicket != NULL) ? *creationTicket : NULL,
                 &name);
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error finish (ExecuteFinish) CreatePrimary: %" PRIx32, r);
-        esysContext->state = _ESYS_STATE_ERRORRESPONSE;
-        goto error_cleanup;;
-    }
+    goto_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Received error from SAPI"
+                        " unmarshalling" ,error_cleanup);
 
+    /* Check name and outPublic for consistency */
     if (!iesys_compare_name(loutPublic, &name))
         goto_error(r, TSS2_ESYS_RC_MALFORMED_RESPONSE,
             "in Public name not equal name in response", error_cleanup);
 
+    /* Update the meta data of the ESYS_TR object */
     objectHandleNode->rsrc.name = name;
     objectHandleNode->rsrc.rsrcType = IESYSC_KEY_RSRC;
     objectHandleNode->rsrc.misc.rsrc_key_pub = *loutPublic;
@@ -404,9 +426,13 @@
     else
         SAFE_FREE(loutPublic);
 
-    esysContext->state = _ESYS_STATE_FINISHED;
+    esysContext->state = _ESYS_STATE_INIT;
+    LOG_DEBUG("context=%p, objectHandle=%p, outPublic=%p,"
+              "creationData=%p, creationHash=%p, creationTicket=%p",
+              esysContext, objectHandle, outPublic,
+              creationData, creationHash, creationTicket);
 
-    return r;
+    return TSS2_RC_SUCCESS;
 
 error_cleanup:
     Esys_TR_Close(esysContext, objectHandle);
@@ -417,5 +443,6 @@
         SAFE_FREE(*creationHash);
     if (creationTicket != NULL)
         SAFE_FREE(*creationTicket);
+
     return r;
 }
diff --git a/src/tss2-esys/api/Esys_DictionaryAttackLockReset.c b/src/tss2-esys/api/Esys_DictionaryAttackLockReset.c
index ac1f647..1ea5735 100644
--- a/src/tss2-esys/api/Esys_DictionaryAttackLockReset.c
+++ b/src/tss2-esys/api/Esys_DictionaryAttackLockReset.c
@@ -135,6 +135,7 @@
     TSS2L_SYS_AUTH_COMMAND auths;
     RSRC_NODE_T *lockHandleNode;
 
+    /* Check context, sequence correctness and set state to error for now */
     if (esysContext == NULL) {
         LOG_ERROR("esyscontext is NULL.");
         return TSS2_ESYS_RC_BAD_REFERENCE;
@@ -142,35 +143,40 @@
     r = iesys_check_sequence_async(esysContext);
     if (r != TSS2_RC_SUCCESS)
         return r;
-    r = check_session_feasability(shandle1, shandle2, shandle3, 1);
-    return_if_error(r, "Check session usage");
+    esysContext->state = _ESYS_STATE_INTERNALERROR;
 
+    /* Check and store input parameters */
+    r = check_session_feasability(shandle1, shandle2, shandle3, 1);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Check session usage");
     store_input_parameters(esysContext, lockHandle);
+
+    /* Retrieve the metadata objects for provided handles */
     r = esys_GetResourceObject(esysContext, lockHandle, &lockHandleNode);
-    if (r != TPM2_RC_SUCCESS)
-        return r;
+    return_state_if_error(r, _ESYS_STATE_INIT, "lockHandle unknown.");
+
+    /* Initial invocation of SAPI to prepare the command buffer with parameters */
     r = Tss2_Sys_DictionaryAttackLockReset_Prepare(esysContext->sys,
                 (lockHandleNode == NULL) ? TPM2_RH_NULL : lockHandleNode->rsrc.handle);
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error async DictionaryAttackLockReset");
-        return r;
-    }
-    r = init_session_tab(esysContext, shandle1, shandle2, shandle3);
-    return_if_error(r, "Initialize session resources");
+    return_state_if_error(r, _ESYS_STATE_INIT, "SAPI Prepare returned error.");
 
+    /* Calculate the cpHash Values */
+    r = init_session_tab(esysContext, shandle1, shandle2, shandle3);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Initialize session resources");
     iesys_compute_session_value(esysContext->session_tab[0],
                 &lockHandleNode->rsrc.name, &lockHandleNode->auth);
-    r = iesys_gen_auths(esysContext, lockHandleNode, NULL, NULL, &auths);
-    return_if_error(r, "Error in computation of auth values");
+    iesys_compute_session_value(esysContext->session_tab[1], NULL, NULL);
+    iesys_compute_session_value(esysContext->session_tab[2], NULL, NULL);
 
+    /* Generate the auth values and set them in the SAPI command buffer */
+    r = iesys_gen_auths(esysContext, lockHandleNode, NULL, NULL, &auths);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Error in computation of auth values");
     esysContext->authsCount = auths.count;
     r = Tss2_Sys_SetCmdAuths(esysContext->sys, &auths);
-    if (r != TSS2_RC_SUCCESS) {
-        return r;
-    }
+    return_state_if_error(r, _ESYS_STATE_INIT, "SAPI error on SetCmdAuths");
 
+    /* Trigger execution and finish the async invocation */
     r = Tss2_Sys_ExecuteAsync(esysContext->sys);
-    return_if_error(r, "Finish (Execute Async)");
+    return_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Finish (Execute Async)");
 
     esysContext->state = _ESYS_STATE_SENT;
 
@@ -194,26 +200,34 @@
     ESYS_CONTEXT *esysContext)
 {
     LOG_TRACE("complete");
+    TSS2_RC r;
     if (esysContext == NULL) {
         LOG_ERROR("esyscontext is NULL.");
         return TSS2_ESYS_RC_BAD_REFERENCE;
     }
+
+    /* Check for correct sequence and set sequence to irregular for now */
     if (esysContext->state != _ESYS_STATE_SENT) {
         LOG_ERROR("Esys called in bad sequence.");
         return TSS2_ESYS_RC_BAD_SEQUENCE;
     }
-    TSS2_RC r;
+    esysContext->state = _ESYS_STATE_INTERNALERROR;
+
+    /*Receive the TPM response and handle resubmissions if necessary. */
     r = Tss2_Sys_ExecuteFinish(esysContext->sys, esysContext->timeout);
     if ((r & ~TSS2_RC_LAYER_MASK) == TSS2_BASE_RC_TRY_AGAIN) {
         LOG_DEBUG("A layer below returned TRY_AGAIN: %" PRIx32, r);
+        esysContext->state = _ESYS_STATE_SENT;
         return r;
     }
+    /* This block handle the resubmission of TPM commands given a certain set of
+     * TPM response codes. */
     if (r == TPM2_RC_RETRY || r == TPM2_RC_TESTING || r == TPM2_RC_YIELDED) {
         LOG_DEBUG("TPM returned RETRY, TESTING or YIELDED, which triggers a "
             "resubmission: %" PRIx32, r);
         if (esysContext->submissionCount >= _ESYS_MAX_SUBMISSIONS) {
-            LOG_WARNING("Maximum number of resubmissions has been reached.");
-            esysContext->state = _ESYS_STATE_ERRORRESPONSE;
+            LOG_WARNING("Maximum number of (re)submissions has been reached.");
+            esysContext->state = _ESYS_STATE_INIT;
             return r;
         }
         esysContext->state = _ESYS_STATE_RESUBMISSION;
@@ -223,33 +237,42 @@
                 esysContext->session_type[1],
                 esysContext->session_type[2]);
         if (r != TSS2_RC_SUCCESS) {
-            LOG_ERROR("Error attempting to resubmit");
+            LOG_WARNING("Error attempting to resubmit");
+            /* We do not set esysContext->state here but inherit the most recent
+             * state of the _async function. */
             return r;
         }
         r = TSS2_ESYS_RC_TRY_AGAIN;
+        LOG_DEBUG("Resubmission initiated and returning RC_TRY_AGAIN.");
         return r;
     }
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error finish (ExecuteFinish) DictionaryAttackLockReset");
+    /* The following is the "regular error" handling. */
+    if (r != TSS2_RC_SUCCESS && (r & TSS2_RC_LAYER_MASK) == 0) {
+        LOG_WARNING("Received TPM Error");
+        esysContext->state = _ESYS_STATE_INIT;
+        return r;
+    } else if (r != TSS2_RC_SUCCESS) {
+        LOG_ERROR("Received a non-TPM Error");
+        esysContext->state = _ESYS_STATE_INTERNALERROR;
         return r;
     }
+
     /*
      * Now the verification of the response (hmac check) and if necessary the
-     * parameter decryption have to be done
+     * parameter decryption have to be done.
      */
     r = iesys_check_response(esysContext);
-    return_if_error(r, "Error: check response");
+    return_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Error: check response");
     /*
      * After the verification of the response we call the complete function
      * to deliver the result.
      */
     r = Tss2_Sys_DictionaryAttackLockReset_Complete(esysContext->sys);
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error finish (ExecuteFinish) DictionaryAttackLockReset: %" PRIx32, r);
-        esysContext->state = _ESYS_STATE_ERRORRESPONSE;
-        return r;;
-    }
-    esysContext->state = _ESYS_STATE_FINISHED;
+    return_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Received error from SAPI"
+                        " unmarshalling" );
+    esysContext->state = _ESYS_STATE_INIT;
+    LOG_DEBUG("context=%p",
+              esysContext);
 
-    return r;
+    return TSS2_RC_SUCCESS;
 }
diff --git a/src/tss2-esys/api/Esys_DictionaryAttackParameters.c b/src/tss2-esys/api/Esys_DictionaryAttackParameters.c
index 8c0e698..d5d5467 100644
--- a/src/tss2-esys/api/Esys_DictionaryAttackParameters.c
+++ b/src/tss2-esys/api/Esys_DictionaryAttackParameters.c
@@ -156,6 +156,7 @@
     TSS2L_SYS_AUTH_COMMAND auths;
     RSRC_NODE_T *lockHandleNode;
 
+    /* Check context, sequence correctness and set state to error for now */
     if (esysContext == NULL) {
         LOG_ERROR("esyscontext is NULL.");
         return TSS2_ESYS_RC_BAD_REFERENCE;
@@ -163,43 +164,46 @@
     r = iesys_check_sequence_async(esysContext);
     if (r != TSS2_RC_SUCCESS)
         return r;
-    r = check_session_feasability(shandle1, shandle2, shandle3, 1);
-    return_if_error(r, "Check session usage");
+    esysContext->state = _ESYS_STATE_INTERNALERROR;
 
+    /* Check and store input parameters */
+    r = check_session_feasability(shandle1, shandle2, shandle3, 1);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Check session usage");
     store_input_parameters(esysContext, lockHandle,
                 newMaxTries,
                 newRecoveryTime,
                 lockoutRecovery);
+
+    /* Retrieve the metadata objects for provided handles */
     r = esys_GetResourceObject(esysContext, lockHandle, &lockHandleNode);
-    if (r != TPM2_RC_SUCCESS)
-        return r;
+    return_state_if_error(r, _ESYS_STATE_INIT, "lockHandle unknown.");
+
+    /* Initial invocation of SAPI to prepare the command buffer with parameters */
     r = Tss2_Sys_DictionaryAttackParameters_Prepare(esysContext->sys,
                 (lockHandleNode == NULL) ? TPM2_RH_NULL : lockHandleNode->rsrc.handle,
                 newMaxTries,
                 newRecoveryTime,
                 lockoutRecovery);
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error async DictionaryAttackParameters");
-        return r;
-    }
-    r = init_session_tab(esysContext, shandle1, shandle2, shandle3);
-    return_if_error(r, "Initialize session resources");
+    return_state_if_error(r, _ESYS_STATE_INIT, "SAPI Prepare returned error.");
 
+    /* Calculate the cpHash Values */
+    r = init_session_tab(esysContext, shandle1, shandle2, shandle3);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Initialize session resources");
     iesys_compute_session_value(esysContext->session_tab[0],
                 &lockHandleNode->rsrc.name, &lockHandleNode->auth);
     iesys_compute_session_value(esysContext->session_tab[1], NULL, NULL);
     iesys_compute_session_value(esysContext->session_tab[2], NULL, NULL);
-    r = iesys_gen_auths(esysContext, lockHandleNode, NULL, NULL, &auths);
-    return_if_error(r, "Error in computation of auth values");
 
+    /* Generate the auth values and set them in the SAPI command buffer */
+    r = iesys_gen_auths(esysContext, lockHandleNode, NULL, NULL, &auths);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Error in computation of auth values");
     esysContext->authsCount = auths.count;
     r = Tss2_Sys_SetCmdAuths(esysContext->sys, &auths);
-    if (r != TSS2_RC_SUCCESS) {
-        return r;
-    }
+    return_state_if_error(r, _ESYS_STATE_INIT, "SAPI error on SetCmdAuths");
 
+    /* Trigger execution and finish the async invocation */
     r = Tss2_Sys_ExecuteAsync(esysContext->sys);
-    return_if_error(r, "Finish (Execute Async)");
+    return_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Finish (Execute Async)");
 
     esysContext->state = _ESYS_STATE_SENT;
 
@@ -223,26 +227,34 @@
     ESYS_CONTEXT *esysContext)
 {
     LOG_TRACE("complete");
+    TSS2_RC r;
     if (esysContext == NULL) {
         LOG_ERROR("esyscontext is NULL.");
         return TSS2_ESYS_RC_BAD_REFERENCE;
     }
+
+    /* Check for correct sequence and set sequence to irregular for now */
     if (esysContext->state != _ESYS_STATE_SENT) {
         LOG_ERROR("Esys called in bad sequence.");
         return TSS2_ESYS_RC_BAD_SEQUENCE;
     }
-    TSS2_RC r;
+    esysContext->state = _ESYS_STATE_INTERNALERROR;
+
+    /*Receive the TPM response and handle resubmissions if necessary. */
     r = Tss2_Sys_ExecuteFinish(esysContext->sys, esysContext->timeout);
     if ((r & ~TSS2_RC_LAYER_MASK) == TSS2_BASE_RC_TRY_AGAIN) {
         LOG_DEBUG("A layer below returned TRY_AGAIN: %" PRIx32, r);
+        esysContext->state = _ESYS_STATE_SENT;
         return r;
     }
+    /* This block handle the resubmission of TPM commands given a certain set of
+     * TPM response codes. */
     if (r == TPM2_RC_RETRY || r == TPM2_RC_TESTING || r == TPM2_RC_YIELDED) {
         LOG_DEBUG("TPM returned RETRY, TESTING or YIELDED, which triggers a "
             "resubmission: %" PRIx32, r);
         if (esysContext->submissionCount >= _ESYS_MAX_SUBMISSIONS) {
-            LOG_WARNING("Maximum number of resubmissions has been reached.");
-            esysContext->state = _ESYS_STATE_ERRORRESPONSE;
+            LOG_WARNING("Maximum number of (re)submissions has been reached.");
+            esysContext->state = _ESYS_STATE_INIT;
             return r;
         }
         esysContext->state = _ESYS_STATE_RESUBMISSION;
@@ -255,33 +267,42 @@
                 esysContext->in.DictionaryAttackParameters.newRecoveryTime,
                 esysContext->in.DictionaryAttackParameters.lockoutRecovery);
         if (r != TSS2_RC_SUCCESS) {
-            LOG_ERROR("Error attempting to resubmit");
+            LOG_WARNING("Error attempting to resubmit");
+            /* We do not set esysContext->state here but inherit the most recent
+             * state of the _async function. */
             return r;
         }
         r = TSS2_ESYS_RC_TRY_AGAIN;
+        LOG_DEBUG("Resubmission initiated and returning RC_TRY_AGAIN.");
         return r;
     }
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error finish (ExecuteFinish) DictionaryAttackParameters");
+    /* The following is the "regular error" handling. */
+    if (r != TSS2_RC_SUCCESS && (r & TSS2_RC_LAYER_MASK) == 0) {
+        LOG_WARNING("Received TPM Error");
+        esysContext->state = _ESYS_STATE_INIT;
+        return r;
+    } else if (r != TSS2_RC_SUCCESS) {
+        LOG_ERROR("Received a non-TPM Error");
+        esysContext->state = _ESYS_STATE_INTERNALERROR;
         return r;
     }
+
     /*
      * Now the verification of the response (hmac check) and if necessary the
-     * parameter decryption have to be done
+     * parameter decryption have to be done.
      */
     r = iesys_check_response(esysContext);
-    return_if_error(r, "Error: check response");
+    return_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Error: check response");
     /*
      * After the verification of the response we call the complete function
      * to deliver the result.
      */
     r = Tss2_Sys_DictionaryAttackParameters_Complete(esysContext->sys);
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error finish (ExecuteFinish) DictionaryAttackParameters: %" PRIx32, r);
-        esysContext->state = _ESYS_STATE_ERRORRESPONSE;
-        return r;;
-    }
-    esysContext->state = _ESYS_STATE_FINISHED;
+    return_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Received error from SAPI"
+                        " unmarshalling" );
+    esysContext->state = _ESYS_STATE_INIT;
+    LOG_DEBUG("context=%p",
+              esysContext);
 
-    return r;
+    return TSS2_RC_SUCCESS;
 }
diff --git a/src/tss2-esys/api/Esys_Duplicate.c b/src/tss2-esys/api/Esys_Duplicate.c
index 09d141b..4185a3a 100644
--- a/src/tss2-esys/api/Esys_Duplicate.c
+++ b/src/tss2-esys/api/Esys_Duplicate.c
@@ -183,6 +183,7 @@
     RSRC_NODE_T *objectHandleNode;
     RSRC_NODE_T *newParentHandleNode;
 
+    /* Check context, sequence correctness and set state to error for now */
     if (esysContext == NULL) {
         LOG_ERROR("esyscontext is NULL.");
         return TSS2_ESYS_RC_BAD_REFERENCE;
@@ -190,45 +191,47 @@
     r = iesys_check_sequence_async(esysContext);
     if (r != TSS2_RC_SUCCESS)
         return r;
-    r = check_session_feasability(shandle1, shandle2, shandle3, 1);
-    return_if_error(r, "Check session usage");
+    esysContext->state = _ESYS_STATE_INTERNALERROR;
 
+    /* Check and store input parameters */
+    r = check_session_feasability(shandle1, shandle2, shandle3, 1);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Check session usage");
     store_input_parameters(esysContext, objectHandle, newParentHandle,
                 encryptionKeyIn,
                 symmetricAlg);
+
+    /* Retrieve the metadata objects for provided handles */
     r = esys_GetResourceObject(esysContext, objectHandle, &objectHandleNode);
-    if (r != TPM2_RC_SUCCESS)
-        return r;
+    return_state_if_error(r, _ESYS_STATE_INIT, "objectHandle unknown.");
     r = esys_GetResourceObject(esysContext, newParentHandle, &newParentHandleNode);
-    if (r != TPM2_RC_SUCCESS)
-        return r;
+    return_state_if_error(r, _ESYS_STATE_INIT, "newParentHandle unknown.");
+
+    /* Initial invocation of SAPI to prepare the command buffer with parameters */
     r = Tss2_Sys_Duplicate_Prepare(esysContext->sys,
                 (objectHandleNode == NULL) ? TPM2_RH_NULL : objectHandleNode->rsrc.handle,
                 (newParentHandleNode == NULL) ? TPM2_RH_NULL : newParentHandleNode->rsrc.handle,
                 encryptionKeyIn,
                 symmetricAlg);
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error async Duplicate");
-        return r;
-    }
-    r = init_session_tab(esysContext, shandle1, shandle2, shandle3);
-    return_if_error(r, "Initialize session resources");
+    return_state_if_error(r, _ESYS_STATE_INIT, "SAPI Prepare returned error.");
 
+    /* Calculate the cpHash Values */
+    r = init_session_tab(esysContext, shandle1, shandle2, shandle3);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Initialize session resources");
     iesys_compute_session_value(esysContext->session_tab[0],
                 &objectHandleNode->rsrc.name, &objectHandleNode->auth);
     iesys_compute_session_value(esysContext->session_tab[1], NULL, NULL);
     iesys_compute_session_value(esysContext->session_tab[2], NULL, NULL);
-    r = iesys_gen_auths(esysContext, objectHandleNode, newParentHandleNode, NULL, &auths);
-    return_if_error(r, "Error in computation of auth values");
 
+    /* Generate the auth values and set them in the SAPI command buffer */
+    r = iesys_gen_auths(esysContext, objectHandleNode, newParentHandleNode, NULL, &auths);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Error in computation of auth values");
     esysContext->authsCount = auths.count;
     r = Tss2_Sys_SetCmdAuths(esysContext->sys, &auths);
-    if (r != TSS2_RC_SUCCESS) {
-        return r;
-    }
+    return_state_if_error(r, _ESYS_STATE_INIT, "SAPI error on SetCmdAuths");
 
+    /* Trigger execution and finish the async invocation */
     r = Tss2_Sys_ExecuteAsync(esysContext->sys);
-    return_if_error(r, "Finish (Execute Async)");
+    return_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Finish (Execute Async)");
 
     esysContext->state = _ESYS_STATE_SENT;
 
@@ -261,15 +264,20 @@
     TPM2B_ENCRYPTED_SECRET **outSymSeed)
 {
     LOG_TRACE("complete");
+    TSS2_RC r;
     if (esysContext == NULL) {
         LOG_ERROR("esyscontext is NULL.");
         return TSS2_ESYS_RC_BAD_REFERENCE;
     }
+
+    /* Check for correct sequence and set sequence to irregular for now */
     if (esysContext->state != _ESYS_STATE_SENT) {
         LOG_ERROR("Esys called in bad sequence.");
         return TSS2_ESYS_RC_BAD_SEQUENCE;
     }
-    TSS2_RC r;
+    esysContext->state = _ESYS_STATE_INTERNALERROR;
+
+    /* Allocate memory for response parameters */
     if (encryptionKeyOut != NULL) {
         *encryptionKeyOut = calloc(sizeof(TPM2B_DATA), 1);
         if (*encryptionKeyOut == NULL) {
@@ -288,17 +296,22 @@
             goto_error(r, TSS2_ESYS_RC_MEMORY, "Out of memory", error_cleanup);
         }
     }
+
+    /*Receive the TPM response and handle resubmissions if necessary. */
     r = Tss2_Sys_ExecuteFinish(esysContext->sys, esysContext->timeout);
     if ((r & ~TSS2_RC_LAYER_MASK) == TSS2_BASE_RC_TRY_AGAIN) {
         LOG_DEBUG("A layer below returned TRY_AGAIN: %" PRIx32, r);
+        esysContext->state = _ESYS_STATE_SENT;
         goto error_cleanup;
     }
+    /* This block handle the resubmission of TPM commands given a certain set of
+     * TPM response codes. */
     if (r == TPM2_RC_RETRY || r == TPM2_RC_TESTING || r == TPM2_RC_YIELDED) {
         LOG_DEBUG("TPM returned RETRY, TESTING or YIELDED, which triggers a "
             "resubmission: %" PRIx32, r);
         if (esysContext->submissionCount >= _ESYS_MAX_SUBMISSIONS) {
-            LOG_WARNING("Maximum number of resubmissions has been reached.");
-            esysContext->state = _ESYS_STATE_ERRORRESPONSE;
+            LOG_WARNING("Maximum number of (re)submissions has been reached.");
+            esysContext->state = _ESYS_STATE_INIT;
             goto error_cleanup;
         }
         esysContext->state = _ESYS_STATE_RESUBMISSION;
@@ -311,22 +324,32 @@
                 esysContext->in.Duplicate.encryptionKeyIn,
                 esysContext->in.Duplicate.symmetricAlg);
         if (r != TSS2_RC_SUCCESS) {
-            LOG_ERROR("Error attempting to resubmit");
+            LOG_WARNING("Error attempting to resubmit");
+            /* We do not set esysContext->state here but inherit the most recent
+             * state of the _async function. */
             goto error_cleanup;
         }
         r = TSS2_ESYS_RC_TRY_AGAIN;
+        LOG_DEBUG("Resubmission initiated and returning RC_TRY_AGAIN.");
         goto error_cleanup;
     }
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error finish (ExecuteFinish) Duplicate");
+    /* The following is the "regular error" handling. */
+    if (r != TSS2_RC_SUCCESS && (r & TSS2_RC_LAYER_MASK) == 0) {
+        LOG_WARNING("Received TPM Error");
+        esysContext->state = _ESYS_STATE_INIT;
+        goto error_cleanup;
+    } else if (r != TSS2_RC_SUCCESS) {
+        LOG_ERROR("Received a non-TPM Error");
+        esysContext->state = _ESYS_STATE_INTERNALERROR;
         goto error_cleanup;
     }
+
     /*
      * Now the verification of the response (hmac check) and if necessary the
-     * parameter decryption have to be done
+     * parameter decryption have to be done.
      */
     r = iesys_check_response(esysContext);
-    goto_if_error(r, "Error: check response",
+    goto_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Error: check response",
                       error_cleanup);
     /*
      * After the verification of the response we call the complete function
@@ -336,14 +359,15 @@
                 (encryptionKeyOut != NULL) ? *encryptionKeyOut : NULL,
                 (duplicate != NULL) ? *duplicate : NULL,
                 (outSymSeed != NULL) ? *outSymSeed : NULL);
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error finish (ExecuteFinish) Duplicate: %" PRIx32, r);
-        esysContext->state = _ESYS_STATE_ERRORRESPONSE;
-        goto error_cleanup;;
-    }
-    esysContext->state = _ESYS_STATE_FINISHED;
+    goto_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Received error from SAPI"
+                        " unmarshalling" ,error_cleanup);
+    esysContext->state = _ESYS_STATE_INIT;
+    LOG_DEBUG("context=%p, encryptionKeyOut=%p, duplicate=%p,"
+              "outSymSeed=%p",
+              esysContext, encryptionKeyOut, duplicate,
+              outSymSeed);
 
-    return r;
+    return TSS2_RC_SUCCESS;
 
 error_cleanup:
     if (encryptionKeyOut != NULL)
@@ -352,5 +376,6 @@
         SAFE_FREE(*duplicate);
     if (outSymSeed != NULL)
         SAFE_FREE(*outSymSeed);
+
     return r;
 }
diff --git a/src/tss2-esys/api/Esys_ECC_Parameters.c b/src/tss2-esys/api/Esys_ECC_Parameters.c
index 14edcac..c5c3aa2 100644
--- a/src/tss2-esys/api/Esys_ECC_Parameters.c
+++ b/src/tss2-esys/api/Esys_ECC_Parameters.c
@@ -136,6 +136,7 @@
     TSS2_RC r;
     TSS2L_SYS_AUTH_COMMAND auths;
 
+    /* Check context, sequence correctness and set state to error for now */
     if (esysContext == NULL) {
         LOG_ERROR("esyscontext is NULL.");
         return TSS2_ESYS_RC_BAD_REFERENCE;
@@ -143,32 +144,36 @@
     r = iesys_check_sequence_async(esysContext);
     if (r != TSS2_RC_SUCCESS)
         return r;
-    r = check_session_feasability(shandle1, shandle2, shandle3, 0);
-    return_if_error(r, "Check session usage");
+    esysContext->state = _ESYS_STATE_INTERNALERROR;
 
+    /* Check and store input parameters */
+    r = check_session_feasability(shandle1, shandle2, shandle3, 0);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Check session usage");
     store_input_parameters(esysContext,
                 curveID);
+
+    /* Initial invocation of SAPI to prepare the command buffer with parameters */
     r = Tss2_Sys_ECC_Parameters_Prepare(esysContext->sys,
                 curveID);
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error async ECC_Parameters");
-        return r;
-    }
+    return_state_if_error(r, _ESYS_STATE_INIT, "SAPI Prepare returned error.");
+
+    /* Calculate the cpHash Values */
     r = init_session_tab(esysContext, shandle1, shandle2, shandle3);
-    return_if_error(r, "Initialize session resources");
-
+    return_state_if_error(r, _ESYS_STATE_INIT, "Initialize session resources");
     iesys_compute_session_value(esysContext->session_tab[0], NULL, NULL);
-    r = iesys_gen_auths(esysContext, NULL, NULL, NULL, &auths);
-    return_if_error(r, "Error in computation of auth values");
+    iesys_compute_session_value(esysContext->session_tab[1], NULL, NULL);
+    iesys_compute_session_value(esysContext->session_tab[2], NULL, NULL);
 
+    /* Generate the auth values and set them in the SAPI command buffer */
+    r = iesys_gen_auths(esysContext, NULL, NULL, NULL, &auths);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Error in computation of auth values");
     esysContext->authsCount = auths.count;
     r = Tss2_Sys_SetCmdAuths(esysContext->sys, &auths);
-    if (r != TSS2_RC_SUCCESS) {
-        return r;
-    }
+    return_state_if_error(r, _ESYS_STATE_INIT, "SAPI error on SetCmdAuths");
 
+    /* Trigger execution and finish the async invocation */
     r = Tss2_Sys_ExecuteAsync(esysContext->sys);
-    return_if_error(r, "Finish (Execute Async)");
+    return_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Finish (Execute Async)");
 
     esysContext->state = _ESYS_STATE_SENT;
 
@@ -195,32 +200,42 @@
     TPMS_ALGORITHM_DETAIL_ECC **parameters)
 {
     LOG_TRACE("complete");
+    TSS2_RC r;
     if (esysContext == NULL) {
         LOG_ERROR("esyscontext is NULL.");
         return TSS2_ESYS_RC_BAD_REFERENCE;
     }
+
+    /* Check for correct sequence and set sequence to irregular for now */
     if (esysContext->state != _ESYS_STATE_SENT) {
         LOG_ERROR("Esys called in bad sequence.");
         return TSS2_ESYS_RC_BAD_SEQUENCE;
     }
-    TSS2_RC r;
+    esysContext->state = _ESYS_STATE_INTERNALERROR;
+
+    /* Allocate memory for response parameters */
     if (parameters != NULL) {
         *parameters = calloc(sizeof(TPMS_ALGORITHM_DETAIL_ECC), 1);
         if (*parameters == NULL) {
             return_error(TSS2_ESYS_RC_MEMORY, "Out of memory");
         }
     }
+
+    /*Receive the TPM response and handle resubmissions if necessary. */
     r = Tss2_Sys_ExecuteFinish(esysContext->sys, esysContext->timeout);
     if ((r & ~TSS2_RC_LAYER_MASK) == TSS2_BASE_RC_TRY_AGAIN) {
         LOG_DEBUG("A layer below returned TRY_AGAIN: %" PRIx32, r);
+        esysContext->state = _ESYS_STATE_SENT;
         goto error_cleanup;
     }
+    /* This block handle the resubmission of TPM commands given a certain set of
+     * TPM response codes. */
     if (r == TPM2_RC_RETRY || r == TPM2_RC_TESTING || r == TPM2_RC_YIELDED) {
         LOG_DEBUG("TPM returned RETRY, TESTING or YIELDED, which triggers a "
             "resubmission: %" PRIx32, r);
         if (esysContext->submissionCount >= _ESYS_MAX_SUBMISSIONS) {
-            LOG_WARNING("Maximum number of resubmissions has been reached.");
-            esysContext->state = _ESYS_STATE_ERRORRESPONSE;
+            LOG_WARNING("Maximum number of (re)submissions has been reached.");
+            esysContext->state = _ESYS_STATE_INIT;
             goto error_cleanup;
         }
         esysContext->state = _ESYS_STATE_RESUBMISSION;
@@ -230,22 +245,32 @@
                 esysContext->session_type[2],
                 esysContext->in.ECC_Parameters.curveID);
         if (r != TSS2_RC_SUCCESS) {
-            LOG_ERROR("Error attempting to resubmit");
+            LOG_WARNING("Error attempting to resubmit");
+            /* We do not set esysContext->state here but inherit the most recent
+             * state of the _async function. */
             goto error_cleanup;
         }
         r = TSS2_ESYS_RC_TRY_AGAIN;
+        LOG_DEBUG("Resubmission initiated and returning RC_TRY_AGAIN.");
         goto error_cleanup;
     }
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error finish (ExecuteFinish) ECC_Parameters");
+    /* The following is the "regular error" handling. */
+    if (r != TSS2_RC_SUCCESS && (r & TSS2_RC_LAYER_MASK) == 0) {
+        LOG_WARNING("Received TPM Error");
+        esysContext->state = _ESYS_STATE_INIT;
+        goto error_cleanup;
+    } else if (r != TSS2_RC_SUCCESS) {
+        LOG_ERROR("Received a non-TPM Error");
+        esysContext->state = _ESYS_STATE_INTERNALERROR;
         goto error_cleanup;
     }
+
     /*
      * Now the verification of the response (hmac check) and if necessary the
-     * parameter decryption have to be done
+     * parameter decryption have to be done.
      */
     r = iesys_check_response(esysContext);
-    goto_if_error(r, "Error: check response",
+    goto_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Error: check response",
                       error_cleanup);
     /*
      * After the verification of the response we call the complete function
@@ -253,17 +278,17 @@
      */
     r = Tss2_Sys_ECC_Parameters_Complete(esysContext->sys,
                 (parameters != NULL) ? *parameters : NULL);
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error finish (ExecuteFinish) ECC_Parameters: %" PRIx32, r);
-        esysContext->state = _ESYS_STATE_ERRORRESPONSE;
-        goto error_cleanup;;
-    }
-    esysContext->state = _ESYS_STATE_FINISHED;
+    goto_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Received error from SAPI"
+                        " unmarshalling" ,error_cleanup);
+    esysContext->state = _ESYS_STATE_INIT;
+    LOG_DEBUG("context=%p, parameters=%p",
+              esysContext, parameters);
 
-    return r;
+    return TSS2_RC_SUCCESS;
 
 error_cleanup:
     if (parameters != NULL)
         SAFE_FREE(*parameters);
+
     return r;
 }
diff --git a/src/tss2-esys/api/Esys_ECDH_KeyGen.c b/src/tss2-esys/api/Esys_ECDH_KeyGen.c
index 7d1b3cb..1d2f390 100644
--- a/src/tss2-esys/api/Esys_ECDH_KeyGen.c
+++ b/src/tss2-esys/api/Esys_ECDH_KeyGen.c
@@ -143,6 +143,7 @@
     TSS2L_SYS_AUTH_COMMAND auths;
     RSRC_NODE_T *keyHandleNode;
 
+    /* Check context, sequence correctness and set state to error for now */
     if (esysContext == NULL) {
         LOG_ERROR("esyscontext is NULL.");
         return TSS2_ESYS_RC_BAD_REFERENCE;
@@ -150,34 +151,39 @@
     r = iesys_check_sequence_async(esysContext);
     if (r != TSS2_RC_SUCCESS)
         return r;
-    r = check_session_feasability(shandle1, shandle2, shandle3, 0);
-    return_if_error(r, "Check session usage");
+    esysContext->state = _ESYS_STATE_INTERNALERROR;
 
+    /* Check and store input parameters */
+    r = check_session_feasability(shandle1, shandle2, shandle3, 0);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Check session usage");
     store_input_parameters(esysContext, keyHandle);
+
+    /* Retrieve the metadata objects for provided handles */
     r = esys_GetResourceObject(esysContext, keyHandle, &keyHandleNode);
-    if (r != TPM2_RC_SUCCESS)
-        return r;
+    return_state_if_error(r, _ESYS_STATE_INIT, "keyHandle unknown.");
+
+    /* Initial invocation of SAPI to prepare the command buffer with parameters */
     r = Tss2_Sys_ECDH_KeyGen_Prepare(esysContext->sys,
                 (keyHandleNode == NULL) ? TPM2_RH_NULL : keyHandleNode->rsrc.handle);
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error async ECDH_KeyGen");
-        return r;
-    }
+    return_state_if_error(r, _ESYS_STATE_INIT, "SAPI Prepare returned error.");
+
+    /* Calculate the cpHash Values */
     r = init_session_tab(esysContext, shandle1, shandle2, shandle3);
-    return_if_error(r, "Initialize session resources");
-
+    return_state_if_error(r, _ESYS_STATE_INIT, "Initialize session resources");
     iesys_compute_session_value(esysContext->session_tab[0], NULL, NULL);
-    r = iesys_gen_auths(esysContext, keyHandleNode, NULL, NULL, &auths);
-    return_if_error(r, "Error in computation of auth values");
+    iesys_compute_session_value(esysContext->session_tab[1], NULL, NULL);
+    iesys_compute_session_value(esysContext->session_tab[2], NULL, NULL);
 
+    /* Generate the auth values and set them in the SAPI command buffer */
+    r = iesys_gen_auths(esysContext, keyHandleNode, NULL, NULL, &auths);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Error in computation of auth values");
     esysContext->authsCount = auths.count;
     r = Tss2_Sys_SetCmdAuths(esysContext->sys, &auths);
-    if (r != TSS2_RC_SUCCESS) {
-        return r;
-    }
+    return_state_if_error(r, _ESYS_STATE_INIT, "SAPI error on SetCmdAuths");
 
+    /* Trigger execution and finish the async invocation */
     r = Tss2_Sys_ExecuteAsync(esysContext->sys);
-    return_if_error(r, "Finish (Execute Async)");
+    return_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Finish (Execute Async)");
 
     esysContext->state = _ESYS_STATE_SENT;
 
@@ -207,15 +213,20 @@
     TPM2B_ECC_POINT **pubPoint)
 {
     LOG_TRACE("complete");
+    TSS2_RC r;
     if (esysContext == NULL) {
         LOG_ERROR("esyscontext is NULL.");
         return TSS2_ESYS_RC_BAD_REFERENCE;
     }
+
+    /* Check for correct sequence and set sequence to irregular for now */
     if (esysContext->state != _ESYS_STATE_SENT) {
         LOG_ERROR("Esys called in bad sequence.");
         return TSS2_ESYS_RC_BAD_SEQUENCE;
     }
-    TSS2_RC r;
+    esysContext->state = _ESYS_STATE_INTERNALERROR;
+
+    /* Allocate memory for response parameters */
     if (zPoint != NULL) {
         *zPoint = calloc(sizeof(TPM2B_ECC_POINT), 1);
         if (*zPoint == NULL) {
@@ -228,17 +239,22 @@
             goto_error(r, TSS2_ESYS_RC_MEMORY, "Out of memory", error_cleanup);
         }
     }
+
+    /*Receive the TPM response and handle resubmissions if necessary. */
     r = Tss2_Sys_ExecuteFinish(esysContext->sys, esysContext->timeout);
     if ((r & ~TSS2_RC_LAYER_MASK) == TSS2_BASE_RC_TRY_AGAIN) {
         LOG_DEBUG("A layer below returned TRY_AGAIN: %" PRIx32, r);
+        esysContext->state = _ESYS_STATE_SENT;
         goto error_cleanup;
     }
+    /* This block handle the resubmission of TPM commands given a certain set of
+     * TPM response codes. */
     if (r == TPM2_RC_RETRY || r == TPM2_RC_TESTING || r == TPM2_RC_YIELDED) {
         LOG_DEBUG("TPM returned RETRY, TESTING or YIELDED, which triggers a "
             "resubmission: %" PRIx32, r);
         if (esysContext->submissionCount >= _ESYS_MAX_SUBMISSIONS) {
-            LOG_WARNING("Maximum number of resubmissions has been reached.");
-            esysContext->state = _ESYS_STATE_ERRORRESPONSE;
+            LOG_WARNING("Maximum number of (re)submissions has been reached.");
+            esysContext->state = _ESYS_STATE_INIT;
             goto error_cleanup;
         }
         esysContext->state = _ESYS_STATE_RESUBMISSION;
@@ -248,22 +264,32 @@
                 esysContext->session_type[1],
                 esysContext->session_type[2]);
         if (r != TSS2_RC_SUCCESS) {
-            LOG_ERROR("Error attempting to resubmit");
+            LOG_WARNING("Error attempting to resubmit");
+            /* We do not set esysContext->state here but inherit the most recent
+             * state of the _async function. */
             goto error_cleanup;
         }
         r = TSS2_ESYS_RC_TRY_AGAIN;
+        LOG_DEBUG("Resubmission initiated and returning RC_TRY_AGAIN.");
         goto error_cleanup;
     }
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error finish (ExecuteFinish) ECDH_KeyGen");
+    /* The following is the "regular error" handling. */
+    if (r != TSS2_RC_SUCCESS && (r & TSS2_RC_LAYER_MASK) == 0) {
+        LOG_WARNING("Received TPM Error");
+        esysContext->state = _ESYS_STATE_INIT;
+        goto error_cleanup;
+    } else if (r != TSS2_RC_SUCCESS) {
+        LOG_ERROR("Received a non-TPM Error");
+        esysContext->state = _ESYS_STATE_INTERNALERROR;
         goto error_cleanup;
     }
+
     /*
      * Now the verification of the response (hmac check) and if necessary the
-     * parameter decryption have to be done
+     * parameter decryption have to be done.
      */
     r = iesys_check_response(esysContext);
-    goto_if_error(r, "Error: check response",
+    goto_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Error: check response",
                       error_cleanup);
     /*
      * After the verification of the response we call the complete function
@@ -272,19 +298,19 @@
     r = Tss2_Sys_ECDH_KeyGen_Complete(esysContext->sys,
                 (zPoint != NULL) ? *zPoint : NULL,
                 (pubPoint != NULL) ? *pubPoint : NULL);
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error finish (ExecuteFinish) ECDH_KeyGen: %" PRIx32, r);
-        esysContext->state = _ESYS_STATE_ERRORRESPONSE;
-        goto error_cleanup;;
-    }
-    esysContext->state = _ESYS_STATE_FINISHED;
+    goto_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Received error from SAPI"
+                        " unmarshalling" ,error_cleanup);
+    esysContext->state = _ESYS_STATE_INIT;
+    LOG_DEBUG("context=%p, zPoint=%p, pubPoint=%p",
+              esysContext, zPoint, pubPoint);
 
-    return r;
+    return TSS2_RC_SUCCESS;
 
 error_cleanup:
     if (zPoint != NULL)
         SAFE_FREE(*zPoint);
     if (pubPoint != NULL)
         SAFE_FREE(*pubPoint);
+
     return r;
 }
diff --git a/src/tss2-esys/api/Esys_ECDH_ZGen.c b/src/tss2-esys/api/Esys_ECDH_ZGen.c
index 488babd..c37d67e 100644
--- a/src/tss2-esys/api/Esys_ECDH_ZGen.c
+++ b/src/tss2-esys/api/Esys_ECDH_ZGen.c
@@ -152,6 +152,7 @@
     TSS2L_SYS_AUTH_COMMAND auths;
     RSRC_NODE_T *keyHandleNode;
 
+    /* Check context, sequence correctness and set state to error for now */
     if (esysContext == NULL) {
         LOG_ERROR("esyscontext is NULL.");
         return TSS2_ESYS_RC_BAD_REFERENCE;
@@ -159,38 +160,42 @@
     r = iesys_check_sequence_async(esysContext);
     if (r != TSS2_RC_SUCCESS)
         return r;
-    r = check_session_feasability(shandle1, shandle2, shandle3, 1);
-    return_if_error(r, "Check session usage");
+    esysContext->state = _ESYS_STATE_INTERNALERROR;
 
+    /* Check and store input parameters */
+    r = check_session_feasability(shandle1, shandle2, shandle3, 1);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Check session usage");
     store_input_parameters(esysContext, keyHandle,
                 inPoint);
+
+    /* Retrieve the metadata objects for provided handles */
     r = esys_GetResourceObject(esysContext, keyHandle, &keyHandleNode);
-    if (r != TPM2_RC_SUCCESS)
-        return r;
+    return_state_if_error(r, _ESYS_STATE_INIT, "keyHandle unknown.");
+
+    /* Initial invocation of SAPI to prepare the command buffer with parameters */
     r = Tss2_Sys_ECDH_ZGen_Prepare(esysContext->sys,
                 (keyHandleNode == NULL) ? TPM2_RH_NULL : keyHandleNode->rsrc.handle,
                 inPoint);
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error async ECDH_ZGen");
-        return r;
-    }
-    r = init_session_tab(esysContext, shandle1, shandle2, shandle3);
-    return_if_error(r, "Initialize session resources");
+    return_state_if_error(r, _ESYS_STATE_INIT, "SAPI Prepare returned error.");
 
+    /* Calculate the cpHash Values */
+    r = init_session_tab(esysContext, shandle1, shandle2, shandle3);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Initialize session resources");
     iesys_compute_session_value(esysContext->session_tab[0],
                 &keyHandleNode->rsrc.name, &keyHandleNode->auth);
     iesys_compute_session_value(esysContext->session_tab[1], NULL, NULL);
-    r = iesys_gen_auths(esysContext, keyHandleNode, NULL, NULL, &auths);
-    return_if_error(r, "Error in computation of auth values");
+    iesys_compute_session_value(esysContext->session_tab[2], NULL, NULL);
 
+    /* Generate the auth values and set them in the SAPI command buffer */
+    r = iesys_gen_auths(esysContext, keyHandleNode, NULL, NULL, &auths);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Error in computation of auth values");
     esysContext->authsCount = auths.count;
     r = Tss2_Sys_SetCmdAuths(esysContext->sys, &auths);
-    if (r != TSS2_RC_SUCCESS) {
-        return r;
-    }
+    return_state_if_error(r, _ESYS_STATE_INIT, "SAPI error on SetCmdAuths");
 
+    /* Trigger execution and finish the async invocation */
     r = Tss2_Sys_ExecuteAsync(esysContext->sys);
-    return_if_error(r, "Finish (Execute Async)");
+    return_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Finish (Execute Async)");
 
     esysContext->state = _ESYS_STATE_SENT;
 
@@ -217,32 +222,42 @@
     TPM2B_ECC_POINT **outPoint)
 {
     LOG_TRACE("complete");
+    TSS2_RC r;
     if (esysContext == NULL) {
         LOG_ERROR("esyscontext is NULL.");
         return TSS2_ESYS_RC_BAD_REFERENCE;
     }
+
+    /* Check for correct sequence and set sequence to irregular for now */
     if (esysContext->state != _ESYS_STATE_SENT) {
         LOG_ERROR("Esys called in bad sequence.");
         return TSS2_ESYS_RC_BAD_SEQUENCE;
     }
-    TSS2_RC r;
+    esysContext->state = _ESYS_STATE_INTERNALERROR;
+
+    /* Allocate memory for response parameters */
     if (outPoint != NULL) {
         *outPoint = calloc(sizeof(TPM2B_ECC_POINT), 1);
         if (*outPoint == NULL) {
             return_error(TSS2_ESYS_RC_MEMORY, "Out of memory");
         }
     }
+
+    /*Receive the TPM response and handle resubmissions if necessary. */
     r = Tss2_Sys_ExecuteFinish(esysContext->sys, esysContext->timeout);
     if ((r & ~TSS2_RC_LAYER_MASK) == TSS2_BASE_RC_TRY_AGAIN) {
         LOG_DEBUG("A layer below returned TRY_AGAIN: %" PRIx32, r);
+        esysContext->state = _ESYS_STATE_SENT;
         goto error_cleanup;
     }
+    /* This block handle the resubmission of TPM commands given a certain set of
+     * TPM response codes. */
     if (r == TPM2_RC_RETRY || r == TPM2_RC_TESTING || r == TPM2_RC_YIELDED) {
         LOG_DEBUG("TPM returned RETRY, TESTING or YIELDED, which triggers a "
             "resubmission: %" PRIx32, r);
         if (esysContext->submissionCount >= _ESYS_MAX_SUBMISSIONS) {
-            LOG_WARNING("Maximum number of resubmissions has been reached.");
-            esysContext->state = _ESYS_STATE_ERRORRESPONSE;
+            LOG_WARNING("Maximum number of (re)submissions has been reached.");
+            esysContext->state = _ESYS_STATE_INIT;
             goto error_cleanup;
         }
         esysContext->state = _ESYS_STATE_RESUBMISSION;
@@ -253,22 +268,32 @@
                 esysContext->session_type[2],
                 esysContext->in.ECDH_ZGen.inPoint);
         if (r != TSS2_RC_SUCCESS) {
-            LOG_ERROR("Error attempting to resubmit");
+            LOG_WARNING("Error attempting to resubmit");
+            /* We do not set esysContext->state here but inherit the most recent
+             * state of the _async function. */
             goto error_cleanup;
         }
         r = TSS2_ESYS_RC_TRY_AGAIN;
+        LOG_DEBUG("Resubmission initiated and returning RC_TRY_AGAIN.");
         goto error_cleanup;
     }
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error finish (ExecuteFinish) ECDH_ZGen");
+    /* The following is the "regular error" handling. */
+    if (r != TSS2_RC_SUCCESS && (r & TSS2_RC_LAYER_MASK) == 0) {
+        LOG_WARNING("Received TPM Error");
+        esysContext->state = _ESYS_STATE_INIT;
+        goto error_cleanup;
+    } else if (r != TSS2_RC_SUCCESS) {
+        LOG_ERROR("Received a non-TPM Error");
+        esysContext->state = _ESYS_STATE_INTERNALERROR;
         goto error_cleanup;
     }
+
     /*
      * Now the verification of the response (hmac check) and if necessary the
-     * parameter decryption have to be done
+     * parameter decryption have to be done.
      */
     r = iesys_check_response(esysContext);
-    goto_if_error(r, "Error: check response",
+    goto_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Error: check response",
                       error_cleanup);
     /*
      * After the verification of the response we call the complete function
@@ -276,17 +301,17 @@
      */
     r = Tss2_Sys_ECDH_ZGen_Complete(esysContext->sys,
                 (outPoint != NULL) ? *outPoint : NULL);
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error finish (ExecuteFinish) ECDH_ZGen: %" PRIx32, r);
-        esysContext->state = _ESYS_STATE_ERRORRESPONSE;
-        goto error_cleanup;;
-    }
-    esysContext->state = _ESYS_STATE_FINISHED;
+    goto_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Received error from SAPI"
+                        " unmarshalling" ,error_cleanup);
+    esysContext->state = _ESYS_STATE_INIT;
+    LOG_DEBUG("context=%p, outPoint=%p",
+              esysContext, outPoint);
 
-    return r;
+    return TSS2_RC_SUCCESS;
 
 error_cleanup:
     if (outPoint != NULL)
         SAFE_FREE(*outPoint);
+
     return r;
 }
diff --git a/src/tss2-esys/api/Esys_EC_Ephemeral.c b/src/tss2-esys/api/Esys_EC_Ephemeral.c
index 32880a7..a8ae270 100644
--- a/src/tss2-esys/api/Esys_EC_Ephemeral.c
+++ b/src/tss2-esys/api/Esys_EC_Ephemeral.c
@@ -140,6 +140,7 @@
     TSS2_RC r;
     TSS2L_SYS_AUTH_COMMAND auths;
 
+    /* Check context, sequence correctness and set state to error for now */
     if (esysContext == NULL) {
         LOG_ERROR("esyscontext is NULL.");
         return TSS2_ESYS_RC_BAD_REFERENCE;
@@ -147,32 +148,36 @@
     r = iesys_check_sequence_async(esysContext);
     if (r != TSS2_RC_SUCCESS)
         return r;
-    r = check_session_feasability(shandle1, shandle2, shandle3, 0);
-    return_if_error(r, "Check session usage");
+    esysContext->state = _ESYS_STATE_INTERNALERROR;
 
+    /* Check and store input parameters */
+    r = check_session_feasability(shandle1, shandle2, shandle3, 0);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Check session usage");
     store_input_parameters(esysContext,
                 curveID);
+
+    /* Initial invocation of SAPI to prepare the command buffer with parameters */
     r = Tss2_Sys_EC_Ephemeral_Prepare(esysContext->sys,
                 curveID);
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error async EC_Ephemeral");
-        return r;
-    }
+    return_state_if_error(r, _ESYS_STATE_INIT, "SAPI Prepare returned error.");
+
+    /* Calculate the cpHash Values */
     r = init_session_tab(esysContext, shandle1, shandle2, shandle3);
-    return_if_error(r, "Initialize session resources");
-
+    return_state_if_error(r, _ESYS_STATE_INIT, "Initialize session resources");
     iesys_compute_session_value(esysContext->session_tab[0], NULL, NULL);
-    r = iesys_gen_auths(esysContext, NULL, NULL, NULL, &auths);
-    return_if_error(r, "Error in computation of auth values");
+    iesys_compute_session_value(esysContext->session_tab[1], NULL, NULL);
+    iesys_compute_session_value(esysContext->session_tab[2], NULL, NULL);
 
+    /* Generate the auth values and set them in the SAPI command buffer */
+    r = iesys_gen_auths(esysContext, NULL, NULL, NULL, &auths);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Error in computation of auth values");
     esysContext->authsCount = auths.count;
     r = Tss2_Sys_SetCmdAuths(esysContext->sys, &auths);
-    if (r != TSS2_RC_SUCCESS) {
-        return r;
-    }
+    return_state_if_error(r, _ESYS_STATE_INIT, "SAPI error on SetCmdAuths");
 
+    /* Trigger execution and finish the async invocation */
     r = Tss2_Sys_ExecuteAsync(esysContext->sys);
-    return_if_error(r, "Finish (Execute Async)");
+    return_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Finish (Execute Async)");
 
     esysContext->state = _ESYS_STATE_SENT;
 
@@ -202,32 +207,42 @@
     UINT16 *counter)
 {
     LOG_TRACE("complete");
+    TSS2_RC r;
     if (esysContext == NULL) {
         LOG_ERROR("esyscontext is NULL.");
         return TSS2_ESYS_RC_BAD_REFERENCE;
     }
+
+    /* Check for correct sequence and set sequence to irregular for now */
     if (esysContext->state != _ESYS_STATE_SENT) {
         LOG_ERROR("Esys called in bad sequence.");
         return TSS2_ESYS_RC_BAD_SEQUENCE;
     }
-    TSS2_RC r;
+    esysContext->state = _ESYS_STATE_INTERNALERROR;
+
+    /* Allocate memory for response parameters */
     if (Q != NULL) {
         *Q = calloc(sizeof(TPM2B_ECC_POINT), 1);
         if (*Q == NULL) {
             return_error(TSS2_ESYS_RC_MEMORY, "Out of memory");
         }
     }
+
+    /*Receive the TPM response and handle resubmissions if necessary. */
     r = Tss2_Sys_ExecuteFinish(esysContext->sys, esysContext->timeout);
     if ((r & ~TSS2_RC_LAYER_MASK) == TSS2_BASE_RC_TRY_AGAIN) {
         LOG_DEBUG("A layer below returned TRY_AGAIN: %" PRIx32, r);
+        esysContext->state = _ESYS_STATE_SENT;
         goto error_cleanup;
     }
+    /* This block handle the resubmission of TPM commands given a certain set of
+     * TPM response codes. */
     if (r == TPM2_RC_RETRY || r == TPM2_RC_TESTING || r == TPM2_RC_YIELDED) {
         LOG_DEBUG("TPM returned RETRY, TESTING or YIELDED, which triggers a "
             "resubmission: %" PRIx32, r);
         if (esysContext->submissionCount >= _ESYS_MAX_SUBMISSIONS) {
-            LOG_WARNING("Maximum number of resubmissions has been reached.");
-            esysContext->state = _ESYS_STATE_ERRORRESPONSE;
+            LOG_WARNING("Maximum number of (re)submissions has been reached.");
+            esysContext->state = _ESYS_STATE_INIT;
             goto error_cleanup;
         }
         esysContext->state = _ESYS_STATE_RESUBMISSION;
@@ -237,22 +252,32 @@
                 esysContext->session_type[2],
                 esysContext->in.EC_Ephemeral.curveID);
         if (r != TSS2_RC_SUCCESS) {
-            LOG_ERROR("Error attempting to resubmit");
+            LOG_WARNING("Error attempting to resubmit");
+            /* We do not set esysContext->state here but inherit the most recent
+             * state of the _async function. */
             goto error_cleanup;
         }
         r = TSS2_ESYS_RC_TRY_AGAIN;
+        LOG_DEBUG("Resubmission initiated and returning RC_TRY_AGAIN.");
         goto error_cleanup;
     }
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error finish (ExecuteFinish) EC_Ephemeral");
+    /* The following is the "regular error" handling. */
+    if (r != TSS2_RC_SUCCESS && (r & TSS2_RC_LAYER_MASK) == 0) {
+        LOG_WARNING("Received TPM Error");
+        esysContext->state = _ESYS_STATE_INIT;
+        goto error_cleanup;
+    } else if (r != TSS2_RC_SUCCESS) {
+        LOG_ERROR("Received a non-TPM Error");
+        esysContext->state = _ESYS_STATE_INTERNALERROR;
         goto error_cleanup;
     }
+
     /*
      * Now the verification of the response (hmac check) and if necessary the
-     * parameter decryption have to be done
+     * parameter decryption have to be done.
      */
     r = iesys_check_response(esysContext);
-    goto_if_error(r, "Error: check response",
+    goto_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Error: check response",
                       error_cleanup);
     /*
      * After the verification of the response we call the complete function
@@ -261,17 +286,17 @@
     r = Tss2_Sys_EC_Ephemeral_Complete(esysContext->sys,
                 (Q != NULL) ? *Q : NULL,
                 counter);
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error finish (ExecuteFinish) EC_Ephemeral: %" PRIx32, r);
-        esysContext->state = _ESYS_STATE_ERRORRESPONSE;
-        goto error_cleanup;;
-    }
-    esysContext->state = _ESYS_STATE_FINISHED;
+    goto_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Received error from SAPI"
+                        " unmarshalling" ,error_cleanup);
+    esysContext->state = _ESYS_STATE_INIT;
+    LOG_DEBUG("context=%p, Q=%p, counter=%p",
+              esysContext, Q, counter);
 
-    return r;
+    return TSS2_RC_SUCCESS;
 
 error_cleanup:
     if (Q != NULL)
         SAFE_FREE(*Q);
+
     return r;
 }
diff --git a/src/tss2-esys/api/Esys_EncryptDecrypt.c b/src/tss2-esys/api/Esys_EncryptDecrypt.c
index f8ba6cb..240ed83 100644
--- a/src/tss2-esys/api/Esys_EncryptDecrypt.c
+++ b/src/tss2-esys/api/Esys_EncryptDecrypt.c
@@ -183,6 +183,7 @@
     TSS2L_SYS_AUTH_COMMAND auths;
     RSRC_NODE_T *keyHandleNode;
 
+    /* Check context, sequence correctness and set state to error for now */
     if (esysContext == NULL) {
         LOG_ERROR("esyscontext is NULL.");
         return TSS2_ESYS_RC_BAD_REFERENCE;
@@ -190,45 +191,48 @@
     r = iesys_check_sequence_async(esysContext);
     if (r != TSS2_RC_SUCCESS)
         return r;
-    r = check_session_feasability(shandle1, shandle2, shandle3, 1);
-    return_if_error(r, "Check session usage");
+    esysContext->state = _ESYS_STATE_INTERNALERROR;
 
+    /* Check and store input parameters */
+    r = check_session_feasability(shandle1, shandle2, shandle3, 1);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Check session usage");
     store_input_parameters(esysContext, keyHandle,
                 decrypt,
                 mode,
                 ivIn,
                 inData);
+
+    /* Retrieve the metadata objects for provided handles */
     r = esys_GetResourceObject(esysContext, keyHandle, &keyHandleNode);
-    if (r != TPM2_RC_SUCCESS)
-        return r;
+    return_state_if_error(r, _ESYS_STATE_INIT, "keyHandle unknown.");
+
+    /* Initial invocation of SAPI to prepare the command buffer with parameters */
     r = Tss2_Sys_EncryptDecrypt_Prepare(esysContext->sys,
                 (keyHandleNode == NULL) ? TPM2_RH_NULL : keyHandleNode->rsrc.handle,
                 decrypt,
                 mode,
                 ivIn,
                 inData);
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error async EncryptDecrypt");
-        return r;
-    }
-    r = init_session_tab(esysContext, shandle1, shandle2, shandle3);
-    return_if_error(r, "Initialize session resources");
+    return_state_if_error(r, _ESYS_STATE_INIT, "SAPI Prepare returned error.");
 
+    /* Calculate the cpHash Values */
+    r = init_session_tab(esysContext, shandle1, shandle2, shandle3);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Initialize session resources");
     iesys_compute_session_value(esysContext->session_tab[0],
                 &keyHandleNode->rsrc.name, &keyHandleNode->auth);
     iesys_compute_session_value(esysContext->session_tab[1], NULL, NULL);
     iesys_compute_session_value(esysContext->session_tab[2], NULL, NULL);
-    r = iesys_gen_auths(esysContext, keyHandleNode, NULL, NULL, &auths);
-    return_if_error(r, "Error in computation of auth values");
 
+    /* Generate the auth values and set them in the SAPI command buffer */
+    r = iesys_gen_auths(esysContext, keyHandleNode, NULL, NULL, &auths);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Error in computation of auth values");
     esysContext->authsCount = auths.count;
     r = Tss2_Sys_SetCmdAuths(esysContext->sys, &auths);
-    if (r != TSS2_RC_SUCCESS) {
-        return r;
-    }
+    return_state_if_error(r, _ESYS_STATE_INIT, "SAPI error on SetCmdAuths");
 
+    /* Trigger execution and finish the async invocation */
     r = Tss2_Sys_ExecuteAsync(esysContext->sys);
-    return_if_error(r, "Finish (Execute Async)");
+    return_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Finish (Execute Async)");
 
     esysContext->state = _ESYS_STATE_SENT;
 
@@ -258,15 +262,20 @@
     TPM2B_IV **ivOut)
 {
     LOG_TRACE("complete");
+    TSS2_RC r;
     if (esysContext == NULL) {
         LOG_ERROR("esyscontext is NULL.");
         return TSS2_ESYS_RC_BAD_REFERENCE;
     }
+
+    /* Check for correct sequence and set sequence to irregular for now */
     if (esysContext->state != _ESYS_STATE_SENT) {
         LOG_ERROR("Esys called in bad sequence.");
         return TSS2_ESYS_RC_BAD_SEQUENCE;
     }
-    TSS2_RC r;
+    esysContext->state = _ESYS_STATE_INTERNALERROR;
+
+    /* Allocate memory for response parameters */
     if (outData != NULL) {
         *outData = calloc(sizeof(TPM2B_MAX_BUFFER), 1);
         if (*outData == NULL) {
@@ -279,17 +288,22 @@
             goto_error(r, TSS2_ESYS_RC_MEMORY, "Out of memory", error_cleanup);
         }
     }
+
+    /*Receive the TPM response and handle resubmissions if necessary. */
     r = Tss2_Sys_ExecuteFinish(esysContext->sys, esysContext->timeout);
     if ((r & ~TSS2_RC_LAYER_MASK) == TSS2_BASE_RC_TRY_AGAIN) {
         LOG_DEBUG("A layer below returned TRY_AGAIN: %" PRIx32, r);
+        esysContext->state = _ESYS_STATE_SENT;
         goto error_cleanup;
     }
+    /* This block handle the resubmission of TPM commands given a certain set of
+     * TPM response codes. */
     if (r == TPM2_RC_RETRY || r == TPM2_RC_TESTING || r == TPM2_RC_YIELDED) {
         LOG_DEBUG("TPM returned RETRY, TESTING or YIELDED, which triggers a "
             "resubmission: %" PRIx32, r);
         if (esysContext->submissionCount >= _ESYS_MAX_SUBMISSIONS) {
-            LOG_WARNING("Maximum number of resubmissions has been reached.");
-            esysContext->state = _ESYS_STATE_ERRORRESPONSE;
+            LOG_WARNING("Maximum number of (re)submissions has been reached.");
+            esysContext->state = _ESYS_STATE_INIT;
             goto error_cleanup;
         }
         esysContext->state = _ESYS_STATE_RESUBMISSION;
@@ -303,22 +317,32 @@
                 esysContext->in.EncryptDecrypt.ivIn,
                 esysContext->in.EncryptDecrypt.inData);
         if (r != TSS2_RC_SUCCESS) {
-            LOG_ERROR("Error attempting to resubmit");
+            LOG_WARNING("Error attempting to resubmit");
+            /* We do not set esysContext->state here but inherit the most recent
+             * state of the _async function. */
             goto error_cleanup;
         }
         r = TSS2_ESYS_RC_TRY_AGAIN;
+        LOG_DEBUG("Resubmission initiated and returning RC_TRY_AGAIN.");
         goto error_cleanup;
     }
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error finish (ExecuteFinish) EncryptDecrypt");
+    /* The following is the "regular error" handling. */
+    if (r != TSS2_RC_SUCCESS && (r & TSS2_RC_LAYER_MASK) == 0) {
+        LOG_WARNING("Received TPM Error");
+        esysContext->state = _ESYS_STATE_INIT;
+        goto error_cleanup;
+    } else if (r != TSS2_RC_SUCCESS) {
+        LOG_ERROR("Received a non-TPM Error");
+        esysContext->state = _ESYS_STATE_INTERNALERROR;
         goto error_cleanup;
     }
+
     /*
      * Now the verification of the response (hmac check) and if necessary the
-     * parameter decryption have to be done
+     * parameter decryption have to be done.
      */
     r = iesys_check_response(esysContext);
-    goto_if_error(r, "Error: check response",
+    goto_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Error: check response",
                       error_cleanup);
     /*
      * After the verification of the response we call the complete function
@@ -327,19 +351,19 @@
     r = Tss2_Sys_EncryptDecrypt_Complete(esysContext->sys,
                 (outData != NULL) ? *outData : NULL,
                 (ivOut != NULL) ? *ivOut : NULL);
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error finish (ExecuteFinish) EncryptDecrypt: %" PRIx32, r);
-        esysContext->state = _ESYS_STATE_ERRORRESPONSE;
-        goto error_cleanup;;
-    }
-    esysContext->state = _ESYS_STATE_FINISHED;
+    goto_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Received error from SAPI"
+                        " unmarshalling" ,error_cleanup);
+    esysContext->state = _ESYS_STATE_INIT;
+    LOG_DEBUG("context=%p, outData=%p, ivOut=%p",
+              esysContext, outData, ivOut);
 
-    return r;
+    return TSS2_RC_SUCCESS;
 
 error_cleanup:
     if (outData != NULL)
         SAFE_FREE(*outData);
     if (ivOut != NULL)
         SAFE_FREE(*ivOut);
+
     return r;
 }
diff --git a/src/tss2-esys/api/Esys_EncryptDecrypt2.c b/src/tss2-esys/api/Esys_EncryptDecrypt2.c
index 6ebb0dc..c7de7bf 100644
--- a/src/tss2-esys/api/Esys_EncryptDecrypt2.c
+++ b/src/tss2-esys/api/Esys_EncryptDecrypt2.c
@@ -183,6 +183,7 @@
     TSS2L_SYS_AUTH_COMMAND auths;
     RSRC_NODE_T *keyHandleNode;
 
+    /* Check context, sequence correctness and set state to error for now */
     if (esysContext == NULL) {
         LOG_ERROR("esyscontext is NULL.");
         return TSS2_ESYS_RC_BAD_REFERENCE;
@@ -190,45 +191,48 @@
     r = iesys_check_sequence_async(esysContext);
     if (r != TSS2_RC_SUCCESS)
         return r;
-    r = check_session_feasability(shandle1, shandle2, shandle3, 1);
-    return_if_error(r, "Check session usage");
+    esysContext->state = _ESYS_STATE_INTERNALERROR;
 
+    /* Check and store input parameters */
+    r = check_session_feasability(shandle1, shandle2, shandle3, 1);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Check session usage");
     store_input_parameters(esysContext, keyHandle,
                 inData,
                 decrypt,
                 mode,
                 ivIn);
+
+    /* Retrieve the metadata objects for provided handles */
     r = esys_GetResourceObject(esysContext, keyHandle, &keyHandleNode);
-    if (r != TPM2_RC_SUCCESS)
-        return r;
+    return_state_if_error(r, _ESYS_STATE_INIT, "keyHandle unknown.");
+
+    /* Initial invocation of SAPI to prepare the command buffer with parameters */
     r = Tss2_Sys_EncryptDecrypt2_Prepare(esysContext->sys,
                 (keyHandleNode == NULL) ? TPM2_RH_NULL : keyHandleNode->rsrc.handle,
                 inData,
                 decrypt,
                 mode,
                 ivIn);
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error async EncryptDecrypt2");
-        return r;
-    }
-    r = init_session_tab(esysContext, shandle1, shandle2, shandle3);
-    return_if_error(r, "Initialize session resources");
+    return_state_if_error(r, _ESYS_STATE_INIT, "SAPI Prepare returned error.");
 
+    /* Calculate the cpHash Values */
+    r = init_session_tab(esysContext, shandle1, shandle2, shandle3);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Initialize session resources");
     iesys_compute_session_value(esysContext->session_tab[0],
                 &keyHandleNode->rsrc.name, &keyHandleNode->auth);
     iesys_compute_session_value(esysContext->session_tab[1], NULL, NULL);
     iesys_compute_session_value(esysContext->session_tab[2], NULL, NULL);
-    r = iesys_gen_auths(esysContext, keyHandleNode, NULL, NULL, &auths);
-    return_if_error(r, "Error in computation of auth values");
 
+    /* Generate the auth values and set them in the SAPI command buffer */
+    r = iesys_gen_auths(esysContext, keyHandleNode, NULL, NULL, &auths);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Error in computation of auth values");
     esysContext->authsCount = auths.count;
     r = Tss2_Sys_SetCmdAuths(esysContext->sys, &auths);
-    if (r != TSS2_RC_SUCCESS) {
-        return r;
-    }
+    return_state_if_error(r, _ESYS_STATE_INIT, "SAPI error on SetCmdAuths");
 
+    /* Trigger execution and finish the async invocation */
     r = Tss2_Sys_ExecuteAsync(esysContext->sys);
-    return_if_error(r, "Finish (Execute Async)");
+    return_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Finish (Execute Async)");
 
     esysContext->state = _ESYS_STATE_SENT;
 
@@ -258,15 +262,20 @@
     TPM2B_IV **ivOut)
 {
     LOG_TRACE("complete");
+    TSS2_RC r;
     if (esysContext == NULL) {
         LOG_ERROR("esyscontext is NULL.");
         return TSS2_ESYS_RC_BAD_REFERENCE;
     }
+
+    /* Check for correct sequence and set sequence to irregular for now */
     if (esysContext->state != _ESYS_STATE_SENT) {
         LOG_ERROR("Esys called in bad sequence.");
         return TSS2_ESYS_RC_BAD_SEQUENCE;
     }
-    TSS2_RC r;
+    esysContext->state = _ESYS_STATE_INTERNALERROR;
+
+    /* Allocate memory for response parameters */
     if (outData != NULL) {
         *outData = calloc(sizeof(TPM2B_MAX_BUFFER), 1);
         if (*outData == NULL) {
@@ -279,17 +288,22 @@
             goto_error(r, TSS2_ESYS_RC_MEMORY, "Out of memory", error_cleanup);
         }
     }
+
+    /*Receive the TPM response and handle resubmissions if necessary. */
     r = Tss2_Sys_ExecuteFinish(esysContext->sys, esysContext->timeout);
     if ((r & ~TSS2_RC_LAYER_MASK) == TSS2_BASE_RC_TRY_AGAIN) {
         LOG_DEBUG("A layer below returned TRY_AGAIN: %" PRIx32, r);
+        esysContext->state = _ESYS_STATE_SENT;
         goto error_cleanup;
     }
+    /* This block handle the resubmission of TPM commands given a certain set of
+     * TPM response codes. */
     if (r == TPM2_RC_RETRY || r == TPM2_RC_TESTING || r == TPM2_RC_YIELDED) {
         LOG_DEBUG("TPM returned RETRY, TESTING or YIELDED, which triggers a "
             "resubmission: %" PRIx32, r);
         if (esysContext->submissionCount >= _ESYS_MAX_SUBMISSIONS) {
-            LOG_WARNING("Maximum number of resubmissions has been reached.");
-            esysContext->state = _ESYS_STATE_ERRORRESPONSE;
+            LOG_WARNING("Maximum number of (re)submissions has been reached.");
+            esysContext->state = _ESYS_STATE_INIT;
             goto error_cleanup;
         }
         esysContext->state = _ESYS_STATE_RESUBMISSION;
@@ -303,22 +317,32 @@
                 esysContext->in.EncryptDecrypt2.mode,
                 esysContext->in.EncryptDecrypt2.ivIn);
         if (r != TSS2_RC_SUCCESS) {
-            LOG_ERROR("Error attempting to resubmit");
+            LOG_WARNING("Error attempting to resubmit");
+            /* We do not set esysContext->state here but inherit the most recent
+             * state of the _async function. */
             goto error_cleanup;
         }
         r = TSS2_ESYS_RC_TRY_AGAIN;
+        LOG_DEBUG("Resubmission initiated and returning RC_TRY_AGAIN.");
         goto error_cleanup;
     }
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error finish (ExecuteFinish) EncryptDecrypt2");
+    /* The following is the "regular error" handling. */
+    if (r != TSS2_RC_SUCCESS && (r & TSS2_RC_LAYER_MASK) == 0) {
+        LOG_WARNING("Received TPM Error");
+        esysContext->state = _ESYS_STATE_INIT;
+        goto error_cleanup;
+    } else if (r != TSS2_RC_SUCCESS) {
+        LOG_ERROR("Received a non-TPM Error");
+        esysContext->state = _ESYS_STATE_INTERNALERROR;
         goto error_cleanup;
     }
+
     /*
      * Now the verification of the response (hmac check) and if necessary the
-     * parameter decryption have to be done
+     * parameter decryption have to be done.
      */
     r = iesys_check_response(esysContext);
-    goto_if_error(r, "Error: check response",
+    goto_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Error: check response",
                       error_cleanup);
     /*
      * After the verification of the response we call the complete function
@@ -327,19 +351,19 @@
     r = Tss2_Sys_EncryptDecrypt2_Complete(esysContext->sys,
                 (outData != NULL) ? *outData : NULL,
                 (ivOut != NULL) ? *ivOut : NULL);
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error finish (ExecuteFinish) EncryptDecrypt2: %" PRIx32, r);
-        esysContext->state = _ESYS_STATE_ERRORRESPONSE;
-        goto error_cleanup;;
-    }
-    esysContext->state = _ESYS_STATE_FINISHED;
+    goto_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Received error from SAPI"
+                        " unmarshalling" ,error_cleanup);
+    esysContext->state = _ESYS_STATE_INIT;
+    LOG_DEBUG("context=%p, outData=%p, ivOut=%p",
+              esysContext, outData, ivOut);
 
-    return r;
+    return TSS2_RC_SUCCESS;
 
 error_cleanup:
     if (outData != NULL)
         SAFE_FREE(*outData);
     if (ivOut != NULL)
         SAFE_FREE(*ivOut);
+
     return r;
 }
diff --git a/src/tss2-esys/api/Esys_EventSequenceComplete.c b/src/tss2-esys/api/Esys_EventSequenceComplete.c
index bfcf324..bd9ba31 100644
--- a/src/tss2-esys/api/Esys_EventSequenceComplete.c
+++ b/src/tss2-esys/api/Esys_EventSequenceComplete.c
@@ -162,6 +162,7 @@
     RSRC_NODE_T *pcrHandleNode;
     RSRC_NODE_T *sequenceHandleNode;
 
+    /* Check context, sequence correctness and set state to error for now */
     if (esysContext == NULL) {
         LOG_ERROR("esyscontext is NULL.");
         return TSS2_ESYS_RC_BAD_REFERENCE;
@@ -169,44 +170,46 @@
     r = iesys_check_sequence_async(esysContext);
     if (r != TSS2_RC_SUCCESS)
         return r;
-    r = check_session_feasability(shandle1, shandle2, shandle3, 1);
-    return_if_error(r, "Check session usage");
+    esysContext->state = _ESYS_STATE_INTERNALERROR;
 
+    /* Check and store input parameters */
+    r = check_session_feasability(shandle1, shandle2, shandle3, 1);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Check session usage");
     store_input_parameters(esysContext, pcrHandle, sequenceHandle,
                 buffer);
+
+    /* Retrieve the metadata objects for provided handles */
     r = esys_GetResourceObject(esysContext, pcrHandle, &pcrHandleNode);
-    if (r != TPM2_RC_SUCCESS)
-        return r;
+    return_state_if_error(r, _ESYS_STATE_INIT, "pcrHandle unknown.");
     r = esys_GetResourceObject(esysContext, sequenceHandle, &sequenceHandleNode);
-    if (r != TPM2_RC_SUCCESS)
-        return r;
+    return_state_if_error(r, _ESYS_STATE_INIT, "sequenceHandle unknown.");
+
+    /* Initial invocation of SAPI to prepare the command buffer with parameters */
     r = Tss2_Sys_EventSequenceComplete_Prepare(esysContext->sys,
                 (pcrHandleNode == NULL) ? TPM2_RH_NULL : pcrHandleNode->rsrc.handle,
                 (sequenceHandleNode == NULL) ? TPM2_RH_NULL : sequenceHandleNode->rsrc.handle,
                 buffer);
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error async EventSequenceComplete");
-        return r;
-    }
-    r = init_session_tab(esysContext, shandle1, shandle2, shandle3);
-    return_if_error(r, "Initialize session resources");
+    return_state_if_error(r, _ESYS_STATE_INIT, "SAPI Prepare returned error.");
 
+    /* Calculate the cpHash Values */
+    r = init_session_tab(esysContext, shandle1, shandle2, shandle3);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Initialize session resources");
     iesys_compute_session_value(esysContext->session_tab[0],
                 &pcrHandleNode->rsrc.name, &pcrHandleNode->auth);
     iesys_compute_session_value(esysContext->session_tab[1],
                 &sequenceHandleNode->rsrc.name, &sequenceHandleNode->auth);
     iesys_compute_session_value(esysContext->session_tab[2], NULL, NULL);
-    r = iesys_gen_auths(esysContext, pcrHandleNode, sequenceHandleNode, NULL, &auths);
-    return_if_error(r, "Error in computation of auth values");
 
+    /* Generate the auth values and set them in the SAPI command buffer */
+    r = iesys_gen_auths(esysContext, pcrHandleNode, sequenceHandleNode, NULL, &auths);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Error in computation of auth values");
     esysContext->authsCount = auths.count;
     r = Tss2_Sys_SetCmdAuths(esysContext->sys, &auths);
-    if (r != TSS2_RC_SUCCESS) {
-        return r;
-    }
+    return_state_if_error(r, _ESYS_STATE_INIT, "SAPI error on SetCmdAuths");
 
+    /* Trigger execution and finish the async invocation */
     r = Tss2_Sys_ExecuteAsync(esysContext->sys);
-    return_if_error(r, "Finish (Execute Async)");
+    return_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Finish (Execute Async)");
 
     esysContext->state = _ESYS_STATE_SENT;
 
@@ -233,32 +236,42 @@
     TPML_DIGEST_VALUES **results)
 {
     LOG_TRACE("complete");
+    TSS2_RC r;
     if (esysContext == NULL) {
         LOG_ERROR("esyscontext is NULL.");
         return TSS2_ESYS_RC_BAD_REFERENCE;
     }
+
+    /* Check for correct sequence and set sequence to irregular for now */
     if (esysContext->state != _ESYS_STATE_SENT) {
         LOG_ERROR("Esys called in bad sequence.");
         return TSS2_ESYS_RC_BAD_SEQUENCE;
     }
-    TSS2_RC r;
+    esysContext->state = _ESYS_STATE_INTERNALERROR;
+
+    /* Allocate memory for response parameters */
     if (results != NULL) {
         *results = calloc(sizeof(TPML_DIGEST_VALUES), 1);
         if (*results == NULL) {
             return_error(TSS2_ESYS_RC_MEMORY, "Out of memory");
         }
     }
+
+    /*Receive the TPM response and handle resubmissions if necessary. */
     r = Tss2_Sys_ExecuteFinish(esysContext->sys, esysContext->timeout);
     if ((r & ~TSS2_RC_LAYER_MASK) == TSS2_BASE_RC_TRY_AGAIN) {
         LOG_DEBUG("A layer below returned TRY_AGAIN: %" PRIx32, r);
+        esysContext->state = _ESYS_STATE_SENT;
         goto error_cleanup;
     }
+    /* This block handle the resubmission of TPM commands given a certain set of
+     * TPM response codes. */
     if (r == TPM2_RC_RETRY || r == TPM2_RC_TESTING || r == TPM2_RC_YIELDED) {
         LOG_DEBUG("TPM returned RETRY, TESTING or YIELDED, which triggers a "
             "resubmission: %" PRIx32, r);
         if (esysContext->submissionCount >= _ESYS_MAX_SUBMISSIONS) {
-            LOG_WARNING("Maximum number of resubmissions has been reached.");
-            esysContext->state = _ESYS_STATE_ERRORRESPONSE;
+            LOG_WARNING("Maximum number of (re)submissions has been reached.");
+            esysContext->state = _ESYS_STATE_INIT;
             goto error_cleanup;
         }
         esysContext->state = _ESYS_STATE_RESUBMISSION;
@@ -270,22 +283,32 @@
                 esysContext->session_type[2],
                 esysContext->in.EventSequenceComplete.buffer);
         if (r != TSS2_RC_SUCCESS) {
-            LOG_ERROR("Error attempting to resubmit");
+            LOG_WARNING("Error attempting to resubmit");
+            /* We do not set esysContext->state here but inherit the most recent
+             * state of the _async function. */
             goto error_cleanup;
         }
         r = TSS2_ESYS_RC_TRY_AGAIN;
+        LOG_DEBUG("Resubmission initiated and returning RC_TRY_AGAIN.");
         goto error_cleanup;
     }
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error finish (ExecuteFinish) EventSequenceComplete");
+    /* The following is the "regular error" handling. */
+    if (r != TSS2_RC_SUCCESS && (r & TSS2_RC_LAYER_MASK) == 0) {
+        LOG_WARNING("Received TPM Error");
+        esysContext->state = _ESYS_STATE_INIT;
+        goto error_cleanup;
+    } else if (r != TSS2_RC_SUCCESS) {
+        LOG_ERROR("Received a non-TPM Error");
+        esysContext->state = _ESYS_STATE_INTERNALERROR;
         goto error_cleanup;
     }
+
     /*
      * Now the verification of the response (hmac check) and if necessary the
-     * parameter decryption have to be done
+     * parameter decryption have to be done.
      */
     r = iesys_check_response(esysContext);
-    goto_if_error(r, "Error: check response",
+    goto_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Error: check response",
                       error_cleanup);
     /*
      * After the verification of the response we call the complete function
@@ -293,17 +316,17 @@
      */
     r = Tss2_Sys_EventSequenceComplete_Complete(esysContext->sys,
                 (results != NULL) ? *results : NULL);
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error finish (ExecuteFinish) EventSequenceComplete: %" PRIx32, r);
-        esysContext->state = _ESYS_STATE_ERRORRESPONSE;
-        goto error_cleanup;;
-    }
-    esysContext->state = _ESYS_STATE_FINISHED;
+    goto_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Received error from SAPI"
+                        " unmarshalling" ,error_cleanup);
+    esysContext->state = _ESYS_STATE_INIT;
+    LOG_DEBUG("context=%p, results=%p",
+              esysContext, results);
 
-    return r;
+    return TSS2_RC_SUCCESS;
 
 error_cleanup:
     if (results != NULL)
         SAFE_FREE(*results);
+
     return r;
 }
diff --git a/src/tss2-esys/api/Esys_EvictControl.c b/src/tss2-esys/api/Esys_EvictControl.c
index bd32aea..c143fb7 100644
--- a/src/tss2-esys/api/Esys_EvictControl.c
+++ b/src/tss2-esys/api/Esys_EvictControl.c
@@ -155,6 +155,7 @@
     RSRC_NODE_T *authNode;
     RSRC_NODE_T *objectHandleNode;
 
+    /* Check context, sequence correctness and set state to error for now */
     if (esysContext == NULL) {
         LOG_ERROR("esyscontext is NULL.");
         return TSS2_ESYS_RC_BAD_REFERENCE;
@@ -162,47 +163,50 @@
     r = iesys_check_sequence_async(esysContext);
     if (r != TSS2_RC_SUCCESS)
         return r;
-    r = check_session_feasability(shandle1, shandle2, shandle3, 1);
-    return_if_error(r, "Check session usage");
+    esysContext->state = _ESYS_STATE_INTERNALERROR;
 
+    /* Check and store input parameters */
+    r = check_session_feasability(shandle1, shandle2, shandle3, 1);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Check session usage");
     store_input_parameters(esysContext, auth, objectHandle,
                 persistentHandle);
+
+    /* Retrieve the metadata objects for provided handles */
     r = esys_GetResourceObject(esysContext, auth, &authNode);
-    if (r != TPM2_RC_SUCCESS)
-        return r;
+    return_state_if_error(r, _ESYS_STATE_INIT, "auth unknown.");
     r = esys_GetResourceObject(esysContext, objectHandle, &objectHandleNode);
-    if (r != TPM2_RC_SUCCESS)
-        return r;
-    if (objectHandleNode != NULL &&
-        iesys_get_handle_type(objectHandleNode->rsrc.handle) == TPM2_HT_PERSISTENT) {
-          persistentHandle = objectHandleNode->rsrc.handle;
+    return_state_if_error(r, _ESYS_STATE_INIT, "objectHandle unknown.");
+     /* Use resource handle if object is already persistent */
+     if (objectHandleNode != NULL &&
+         iesys_get_handle_type(objectHandleNode->rsrc.handle) == TPM2_HT_PERSISTENT) {
+         persistentHandle = objectHandleNode->rsrc.handle;
     }
+
+    /* Initial invocation of SAPI to prepare the command buffer with parameters */
     r = Tss2_Sys_EvictControl_Prepare(esysContext->sys,
                 (authNode == NULL) ? TPM2_RH_NULL : authNode->rsrc.handle,
                 (objectHandleNode == NULL) ? TPM2_RH_NULL : objectHandleNode->rsrc.handle,
                 persistentHandle);
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error async EvictControl");
-        return r;
-    }
-    r = init_session_tab(esysContext, shandle1, shandle2, shandle3);
-    return_if_error(r, "Initialize session resources");
+    return_state_if_error(r, _ESYS_STATE_INIT, "SAPI Prepare returned error.");
 
+    /* Calculate the cpHash Values */
+    r = init_session_tab(esysContext, shandle1, shandle2, shandle3);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Initialize session resources");
     iesys_compute_session_value(esysContext->session_tab[0],
                 &authNode->rsrc.name, &authNode->auth);
     iesys_compute_session_value(esysContext->session_tab[1], NULL, NULL);
     iesys_compute_session_value(esysContext->session_tab[2], NULL, NULL);
-    r = iesys_gen_auths(esysContext, authNode, objectHandleNode, NULL, &auths);
-    return_if_error(r, "Error in computation of auth values");
 
+    /* Generate the auth values and set them in the SAPI command buffer */
+    r = iesys_gen_auths(esysContext, authNode, objectHandleNode, NULL, &auths);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Error in computation of auth values");
     esysContext->authsCount = auths.count;
     r = Tss2_Sys_SetCmdAuths(esysContext->sys, &auths);
-    if (r != TSS2_RC_SUCCESS) {
-        return r;
-    }
+    return_state_if_error(r, _ESYS_STATE_INIT, "SAPI error on SetCmdAuths");
 
+    /* Trigger execution and finish the async invocation */
     r = Tss2_Sys_ExecuteAsync(esysContext->sys);
-    return_if_error(r, "Finish (Execute Async)");
+    return_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Finish (Execute Async)");
 
     esysContext->state = _ESYS_STATE_SENT;
 
@@ -228,18 +232,22 @@
     ESYS_TR *newObjectHandle)
 {
     LOG_TRACE("complete");
+    TSS2_RC r;
     if (esysContext == NULL) {
         LOG_ERROR("esyscontext is NULL.");
         return TSS2_ESYS_RC_BAD_REFERENCE;
     }
+
+    /* Check for correct sequence and set sequence to irregular for now */
     if (esysContext->state != _ESYS_STATE_SENT) {
         LOG_ERROR("Esys called in bad sequence.");
         return TSS2_ESYS_RC_BAD_SEQUENCE;
     }
-    TSS2_RC r;
-    IESYS_RESOURCE *newObjectHandleRsrc = NULL;
+    esysContext->state = _ESYS_STATE_INTERNALERROR;
     RSRC_NODE_T *newObjectHandleNode = NULL;
 
+
+    /* Allocate memory for response parameters */
     if (newObjectHandle == NULL) {
         LOG_ERROR("Handle newObjectHandle may not be NULL");
         return TSS2_ESYS_RC_BAD_REFERENCE;
@@ -249,17 +257,22 @@
     if (r != TSS2_RC_SUCCESS)
         return r;
 
+
+    /*Receive the TPM response and handle resubmissions if necessary. */
     r = Tss2_Sys_ExecuteFinish(esysContext->sys, esysContext->timeout);
     if ((r & ~TSS2_RC_LAYER_MASK) == TSS2_BASE_RC_TRY_AGAIN) {
         LOG_DEBUG("A layer below returned TRY_AGAIN: %" PRIx32, r);
+        esysContext->state = _ESYS_STATE_SENT;
         goto error_cleanup;
     }
+    /* This block handle the resubmission of TPM commands given a certain set of
+     * TPM response codes. */
     if (r == TPM2_RC_RETRY || r == TPM2_RC_TESTING || r == TPM2_RC_YIELDED) {
         LOG_DEBUG("TPM returned RETRY, TESTING or YIELDED, which triggers a "
             "resubmission: %" PRIx32, r);
         if (esysContext->submissionCount >= _ESYS_MAX_SUBMISSIONS) {
-            LOG_WARNING("Maximum number of resubmissions has been reached.");
-            esysContext->state = _ESYS_STATE_ERRORRESPONSE;
+            LOG_WARNING("Maximum number of (re)submissions has been reached.");
+            esysContext->state = _ESYS_STATE_INIT;
             goto error_cleanup;
         }
         esysContext->state = _ESYS_STATE_RESUBMISSION;
@@ -271,41 +284,50 @@
                 esysContext->session_type[2],
                 esysContext->in.EvictControl.persistentHandle);
         if (r != TSS2_RC_SUCCESS) {
-            LOG_ERROR("Error attempting to resubmit");
+            LOG_WARNING("Error attempting to resubmit");
+            /* We do not set esysContext->state here but inherit the most recent
+             * state of the _async function. */
             goto error_cleanup;
         }
         r = TSS2_ESYS_RC_TRY_AGAIN;
+        LOG_DEBUG("Resubmission initiated and returning RC_TRY_AGAIN.");
         goto error_cleanup;
     }
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error finish (ExecuteFinish) EvictControl");
+    /* The following is the "regular error" handling. */
+    if (r != TSS2_RC_SUCCESS && (r & TSS2_RC_LAYER_MASK) == 0) {
+        LOG_WARNING("Received TPM Error");
+        esysContext->state = _ESYS_STATE_INIT;
+        goto error_cleanup;
+    } else if (r != TSS2_RC_SUCCESS) {
+        LOG_ERROR("Received a non-TPM Error");
+        esysContext->state = _ESYS_STATE_INTERNALERROR;
         goto error_cleanup;
     }
+
     /*
      * Now the verification of the response (hmac check) and if necessary the
-     * parameter decryption have to be done
+     * parameter decryption have to be done.
      */
     r = iesys_check_response(esysContext);
-    goto_if_error(r, "Error: check response",
+    goto_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Error: check response",
                       error_cleanup);
     /*
      * After the verification of the response we call the complete function
      * to deliver the result.
      */
     r = Tss2_Sys_EvictControl_Complete(esysContext->sys);
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error finish (ExecuteFinish) EvictControl: %" PRIx32, r);
-        esysContext->state = _ESYS_STATE_ERRORRESPONSE;
-        goto error_cleanup;;
-    }
+    goto_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Received error from SAPI"
+                        " unmarshalling" ,error_cleanup);
     ESYS_TR objectHandle = esysContext->in.EvictControl.objectHandle;
     RSRC_NODE_T *objectHandleNode;
     r = esys_GetResourceObject(esysContext, objectHandle, &objectHandleNode);
     goto_if_error(r, "get resource", error_cleanup);
 
+    /* The object was already persistent */
     if (iesys_get_handle_type(objectHandleNode->rsrc.handle) == TPM2_HT_PERSISTENT) {
         *newObjectHandle = ESYS_TR_NONE;
     } else {
+        /* A new resource is created and updated with date from the not persistent object */
         RSRC_NODE_T *newObjectHandleNode = NULL;
         *newObjectHandle = esysContext->esys_handle_cnt++;
         r = esys_CreateResourceObject(esysContext, *newObjectHandle, &newObjectHandleNode);
@@ -315,11 +337,14 @@
         newObjectHandleNode->rsrc = objectHandleNode->rsrc;
         newObjectHandleNode->rsrc.handle = esysContext->in.EvictControl.persistentHandle;
     }
-    esysContext->state = _ESYS_STATE_FINISHED;
+    esysContext->state = _ESYS_STATE_INIT;
+    LOG_DEBUG("context=%p, newObjectHandle=%p",
+              esysContext, newObjectHandle);
 
-    return r;
+    return TSS2_RC_SUCCESS;
 
 error_cleanup:
     Esys_TR_Close(esysContext, newObjectHandle);
+
     return r;
 }
diff --git a/src/tss2-esys/api/Esys_FieldUpgradeData.c b/src/tss2-esys/api/Esys_FieldUpgradeData.c
index ef09edc..2782f55 100644
--- a/src/tss2-esys/api/Esys_FieldUpgradeData.c
+++ b/src/tss2-esys/api/Esys_FieldUpgradeData.c
@@ -146,6 +146,7 @@
     TSS2_RC r;
     TSS2L_SYS_AUTH_COMMAND auths;
 
+    /* Check context, sequence correctness and set state to error for now */
     if (esysContext == NULL) {
         LOG_ERROR("esyscontext is NULL.");
         return TSS2_ESYS_RC_BAD_REFERENCE;
@@ -153,32 +154,36 @@
     r = iesys_check_sequence_async(esysContext);
     if (r != TSS2_RC_SUCCESS)
         return r;
-    r = check_session_feasability(shandle1, shandle2, shandle3, 0);
-    return_if_error(r, "Check session usage");
+    esysContext->state = _ESYS_STATE_INTERNALERROR;
 
+    /* Check and store input parameters */
+    r = check_session_feasability(shandle1, shandle2, shandle3, 0);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Check session usage");
     store_input_parameters(esysContext,
                 fuData);
+
+    /* Initial invocation of SAPI to prepare the command buffer with parameters */
     r = Tss2_Sys_FieldUpgradeData_Prepare(esysContext->sys,
                 fuData);
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error async FieldUpgradeData");
-        return r;
-    }
+    return_state_if_error(r, _ESYS_STATE_INIT, "SAPI Prepare returned error.");
+
+    /* Calculate the cpHash Values */
     r = init_session_tab(esysContext, shandle1, shandle2, shandle3);
-    return_if_error(r, "Initialize session resources");
-
+    return_state_if_error(r, _ESYS_STATE_INIT, "Initialize session resources");
     iesys_compute_session_value(esysContext->session_tab[0], NULL, NULL);
-    r = iesys_gen_auths(esysContext, NULL, NULL, NULL, &auths);
-    return_if_error(r, "Error in computation of auth values");
+    iesys_compute_session_value(esysContext->session_tab[1], NULL, NULL);
+    iesys_compute_session_value(esysContext->session_tab[2], NULL, NULL);
 
+    /* Generate the auth values and set them in the SAPI command buffer */
+    r = iesys_gen_auths(esysContext, NULL, NULL, NULL, &auths);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Error in computation of auth values");
     esysContext->authsCount = auths.count;
     r = Tss2_Sys_SetCmdAuths(esysContext->sys, &auths);
-    if (r != TSS2_RC_SUCCESS) {
-        return r;
-    }
+    return_state_if_error(r, _ESYS_STATE_INIT, "SAPI error on SetCmdAuths");
 
+    /* Trigger execution and finish the async invocation */
     r = Tss2_Sys_ExecuteAsync(esysContext->sys);
-    return_if_error(r, "Finish (Execute Async)");
+    return_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Finish (Execute Async)");
 
     esysContext->state = _ESYS_STATE_SENT;
 
@@ -208,15 +213,20 @@
     TPMT_HA **firstDigest)
 {
     LOG_TRACE("complete");
+    TSS2_RC r;
     if (esysContext == NULL) {
         LOG_ERROR("esyscontext is NULL.");
         return TSS2_ESYS_RC_BAD_REFERENCE;
     }
+
+    /* Check for correct sequence and set sequence to irregular for now */
     if (esysContext->state != _ESYS_STATE_SENT) {
         LOG_ERROR("Esys called in bad sequence.");
         return TSS2_ESYS_RC_BAD_SEQUENCE;
     }
-    TSS2_RC r;
+    esysContext->state = _ESYS_STATE_INTERNALERROR;
+
+    /* Allocate memory for response parameters */
     if (nextDigest != NULL) {
         *nextDigest = calloc(sizeof(TPMT_HA), 1);
         if (*nextDigest == NULL) {
@@ -229,17 +239,22 @@
             goto_error(r, TSS2_ESYS_RC_MEMORY, "Out of memory", error_cleanup);
         }
     }
+
+    /*Receive the TPM response and handle resubmissions if necessary. */
     r = Tss2_Sys_ExecuteFinish(esysContext->sys, esysContext->timeout);
     if ((r & ~TSS2_RC_LAYER_MASK) == TSS2_BASE_RC_TRY_AGAIN) {
         LOG_DEBUG("A layer below returned TRY_AGAIN: %" PRIx32, r);
+        esysContext->state = _ESYS_STATE_SENT;
         goto error_cleanup;
     }
+    /* This block handle the resubmission of TPM commands given a certain set of
+     * TPM response codes. */
     if (r == TPM2_RC_RETRY || r == TPM2_RC_TESTING || r == TPM2_RC_YIELDED) {
         LOG_DEBUG("TPM returned RETRY, TESTING or YIELDED, which triggers a "
             "resubmission: %" PRIx32, r);
         if (esysContext->submissionCount >= _ESYS_MAX_SUBMISSIONS) {
-            LOG_WARNING("Maximum number of resubmissions has been reached.");
-            esysContext->state = _ESYS_STATE_ERRORRESPONSE;
+            LOG_WARNING("Maximum number of (re)submissions has been reached.");
+            esysContext->state = _ESYS_STATE_INIT;
             goto error_cleanup;
         }
         esysContext->state = _ESYS_STATE_RESUBMISSION;
@@ -249,22 +264,32 @@
                 esysContext->session_type[2],
                 esysContext->in.FieldUpgradeData.fuData);
         if (r != TSS2_RC_SUCCESS) {
-            LOG_ERROR("Error attempting to resubmit");
+            LOG_WARNING("Error attempting to resubmit");
+            /* We do not set esysContext->state here but inherit the most recent
+             * state of the _async function. */
             goto error_cleanup;
         }
         r = TSS2_ESYS_RC_TRY_AGAIN;
+        LOG_DEBUG("Resubmission initiated and returning RC_TRY_AGAIN.");
         goto error_cleanup;
     }
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error finish (ExecuteFinish) FieldUpgradeData");
+    /* The following is the "regular error" handling. */
+    if (r != TSS2_RC_SUCCESS && (r & TSS2_RC_LAYER_MASK) == 0) {
+        LOG_WARNING("Received TPM Error");
+        esysContext->state = _ESYS_STATE_INIT;
+        goto error_cleanup;
+    } else if (r != TSS2_RC_SUCCESS) {
+        LOG_ERROR("Received a non-TPM Error");
+        esysContext->state = _ESYS_STATE_INTERNALERROR;
         goto error_cleanup;
     }
+
     /*
      * Now the verification of the response (hmac check) and if necessary the
-     * parameter decryption have to be done
+     * parameter decryption have to be done.
      */
     r = iesys_check_response(esysContext);
-    goto_if_error(r, "Error: check response",
+    goto_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Error: check response",
                       error_cleanup);
     /*
      * After the verification of the response we call the complete function
@@ -273,19 +298,19 @@
     r = Tss2_Sys_FieldUpgradeData_Complete(esysContext->sys,
                 (nextDigest != NULL) ? *nextDigest : NULL,
                 (firstDigest != NULL) ? *firstDigest : NULL);
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error finish (ExecuteFinish) FieldUpgradeData: %" PRIx32, r);
-        esysContext->state = _ESYS_STATE_ERRORRESPONSE;
-        goto error_cleanup;;
-    }
-    esysContext->state = _ESYS_STATE_FINISHED;
+    goto_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Received error from SAPI"
+                        " unmarshalling" ,error_cleanup);
+    esysContext->state = _ESYS_STATE_INIT;
+    LOG_DEBUG("context=%p, nextDigest=%p, firstDigest=%p",
+              esysContext, nextDigest, firstDigest);
 
-    return r;
+    return TSS2_RC_SUCCESS;
 
 error_cleanup:
     if (nextDigest != NULL)
         SAFE_FREE(*nextDigest);
     if (firstDigest != NULL)
         SAFE_FREE(*firstDigest);
+
     return r;
 }
diff --git a/src/tss2-esys/api/Esys_FieldUpgradeStart.c b/src/tss2-esys/api/Esys_FieldUpgradeStart.c
index 4ecdcec..440cd44 100644
--- a/src/tss2-esys/api/Esys_FieldUpgradeStart.c
+++ b/src/tss2-esys/api/Esys_FieldUpgradeStart.c
@@ -171,6 +171,7 @@
     RSRC_NODE_T *authorizationNode;
     RSRC_NODE_T *keyHandleNode;
 
+    /* Check context, sequence correctness and set state to error for now */
     if (esysContext == NULL) {
         LOG_ERROR("esyscontext is NULL.");
         return TSS2_ESYS_RC_BAD_REFERENCE;
@@ -178,45 +179,47 @@
     r = iesys_check_sequence_async(esysContext);
     if (r != TSS2_RC_SUCCESS)
         return r;
-    r = check_session_feasability(shandle1, shandle2, shandle3, 1);
-    return_if_error(r, "Check session usage");
+    esysContext->state = _ESYS_STATE_INTERNALERROR;
 
+    /* Check and store input parameters */
+    r = check_session_feasability(shandle1, shandle2, shandle3, 1);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Check session usage");
     store_input_parameters(esysContext, authorization, keyHandle,
                 fuDigest,
                 manifestSignature);
+
+    /* Retrieve the metadata objects for provided handles */
     r = esys_GetResourceObject(esysContext, authorization, &authorizationNode);
-    if (r != TPM2_RC_SUCCESS)
-        return r;
+    return_state_if_error(r, _ESYS_STATE_INIT, "authorization unknown.");
     r = esys_GetResourceObject(esysContext, keyHandle, &keyHandleNode);
-    if (r != TPM2_RC_SUCCESS)
-        return r;
+    return_state_if_error(r, _ESYS_STATE_INIT, "keyHandle unknown.");
+
+    /* Initial invocation of SAPI to prepare the command buffer with parameters */
     r = Tss2_Sys_FieldUpgradeStart_Prepare(esysContext->sys,
                 (authorizationNode == NULL) ? TPM2_RH_NULL : authorizationNode->rsrc.handle,
                 (keyHandleNode == NULL) ? TPM2_RH_NULL : keyHandleNode->rsrc.handle,
                 fuDigest,
                 manifestSignature);
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error async FieldUpgradeStart");
-        return r;
-    }
-    r = init_session_tab(esysContext, shandle1, shandle2, shandle3);
-    return_if_error(r, "Initialize session resources");
+    return_state_if_error(r, _ESYS_STATE_INIT, "SAPI Prepare returned error.");
 
+    /* Calculate the cpHash Values */
+    r = init_session_tab(esysContext, shandle1, shandle2, shandle3);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Initialize session resources");
     iesys_compute_session_value(esysContext->session_tab[0],
                 &authorizationNode->rsrc.name, &authorizationNode->auth);
     iesys_compute_session_value(esysContext->session_tab[1], NULL, NULL);
     iesys_compute_session_value(esysContext->session_tab[2], NULL, NULL);
-    r = iesys_gen_auths(esysContext, authorizationNode, keyHandleNode, NULL, &auths);
-    return_if_error(r, "Error in computation of auth values");
 
+    /* Generate the auth values and set them in the SAPI command buffer */
+    r = iesys_gen_auths(esysContext, authorizationNode, keyHandleNode, NULL, &auths);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Error in computation of auth values");
     esysContext->authsCount = auths.count;
     r = Tss2_Sys_SetCmdAuths(esysContext->sys, &auths);
-    if (r != TSS2_RC_SUCCESS) {
-        return r;
-    }
+    return_state_if_error(r, _ESYS_STATE_INIT, "SAPI error on SetCmdAuths");
 
+    /* Trigger execution and finish the async invocation */
     r = Tss2_Sys_ExecuteAsync(esysContext->sys);
-    return_if_error(r, "Finish (Execute Async)");
+    return_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Finish (Execute Async)");
 
     esysContext->state = _ESYS_STATE_SENT;
 
@@ -240,26 +243,34 @@
     ESYS_CONTEXT *esysContext)
 {
     LOG_TRACE("complete");
+    TSS2_RC r;
     if (esysContext == NULL) {
         LOG_ERROR("esyscontext is NULL.");
         return TSS2_ESYS_RC_BAD_REFERENCE;
     }
+
+    /* Check for correct sequence and set sequence to irregular for now */
     if (esysContext->state != _ESYS_STATE_SENT) {
         LOG_ERROR("Esys called in bad sequence.");
         return TSS2_ESYS_RC_BAD_SEQUENCE;
     }
-    TSS2_RC r;
+    esysContext->state = _ESYS_STATE_INTERNALERROR;
+
+    /*Receive the TPM response and handle resubmissions if necessary. */
     r = Tss2_Sys_ExecuteFinish(esysContext->sys, esysContext->timeout);
     if ((r & ~TSS2_RC_LAYER_MASK) == TSS2_BASE_RC_TRY_AGAIN) {
         LOG_DEBUG("A layer below returned TRY_AGAIN: %" PRIx32, r);
+        esysContext->state = _ESYS_STATE_SENT;
         return r;
     }
+    /* This block handle the resubmission of TPM commands given a certain set of
+     * TPM response codes. */
     if (r == TPM2_RC_RETRY || r == TPM2_RC_TESTING || r == TPM2_RC_YIELDED) {
         LOG_DEBUG("TPM returned RETRY, TESTING or YIELDED, which triggers a "
             "resubmission: %" PRIx32, r);
         if (esysContext->submissionCount >= _ESYS_MAX_SUBMISSIONS) {
-            LOG_WARNING("Maximum number of resubmissions has been reached.");
-            esysContext->state = _ESYS_STATE_ERRORRESPONSE;
+            LOG_WARNING("Maximum number of (re)submissions has been reached.");
+            esysContext->state = _ESYS_STATE_INIT;
             return r;
         }
         esysContext->state = _ESYS_STATE_RESUBMISSION;
@@ -272,33 +283,42 @@
                 esysContext->in.FieldUpgradeStart.fuDigest,
                 esysContext->in.FieldUpgradeStart.manifestSignature);
         if (r != TSS2_RC_SUCCESS) {
-            LOG_ERROR("Error attempting to resubmit");
+            LOG_WARNING("Error attempting to resubmit");
+            /* We do not set esysContext->state here but inherit the most recent
+             * state of the _async function. */
             return r;
         }
         r = TSS2_ESYS_RC_TRY_AGAIN;
+        LOG_DEBUG("Resubmission initiated and returning RC_TRY_AGAIN.");
         return r;
     }
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error finish (ExecuteFinish) FieldUpgradeStart");
+    /* The following is the "regular error" handling. */
+    if (r != TSS2_RC_SUCCESS && (r & TSS2_RC_LAYER_MASK) == 0) {
+        LOG_WARNING("Received TPM Error");
+        esysContext->state = _ESYS_STATE_INIT;
+        return r;
+    } else if (r != TSS2_RC_SUCCESS) {
+        LOG_ERROR("Received a non-TPM Error");
+        esysContext->state = _ESYS_STATE_INTERNALERROR;
         return r;
     }
+
     /*
      * Now the verification of the response (hmac check) and if necessary the
-     * parameter decryption have to be done
+     * parameter decryption have to be done.
      */
     r = iesys_check_response(esysContext);
-    return_if_error(r, "Error: check response");
+    return_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Error: check response");
     /*
      * After the verification of the response we call the complete function
      * to deliver the result.
      */
     r = Tss2_Sys_FieldUpgradeStart_Complete(esysContext->sys);
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error finish (ExecuteFinish) FieldUpgradeStart: %" PRIx32, r);
-        esysContext->state = _ESYS_STATE_ERRORRESPONSE;
-        return r;;
-    }
-    esysContext->state = _ESYS_STATE_FINISHED;
+    return_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Received error from SAPI"
+                        " unmarshalling" );
+    esysContext->state = _ESYS_STATE_INIT;
+    LOG_DEBUG("context=%p",
+              esysContext);
 
-    return r;
+    return TSS2_RC_SUCCESS;
 }
diff --git a/src/tss2-esys/api/Esys_FirmwareRead.c b/src/tss2-esys/api/Esys_FirmwareRead.c
index b9e5b0a..28bb99f 100644
--- a/src/tss2-esys/api/Esys_FirmwareRead.c
+++ b/src/tss2-esys/api/Esys_FirmwareRead.c
@@ -136,6 +136,7 @@
     TSS2_RC r;
     TSS2L_SYS_AUTH_COMMAND auths;
 
+    /* Check context, sequence correctness and set state to error for now */
     if (esysContext == NULL) {
         LOG_ERROR("esyscontext is NULL.");
         return TSS2_ESYS_RC_BAD_REFERENCE;
@@ -143,32 +144,36 @@
     r = iesys_check_sequence_async(esysContext);
     if (r != TSS2_RC_SUCCESS)
         return r;
-    r = check_session_feasability(shandle1, shandle2, shandle3, 0);
-    return_if_error(r, "Check session usage");
+    esysContext->state = _ESYS_STATE_INTERNALERROR;
 
+    /* Check and store input parameters */
+    r = check_session_feasability(shandle1, shandle2, shandle3, 0);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Check session usage");
     store_input_parameters(esysContext,
                 sequenceNumber);
+
+    /* Initial invocation of SAPI to prepare the command buffer with parameters */
     r = Tss2_Sys_FirmwareRead_Prepare(esysContext->sys,
                 sequenceNumber);
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error async FirmwareRead");
-        return r;
-    }
+    return_state_if_error(r, _ESYS_STATE_INIT, "SAPI Prepare returned error.");
+
+    /* Calculate the cpHash Values */
     r = init_session_tab(esysContext, shandle1, shandle2, shandle3);
-    return_if_error(r, "Initialize session resources");
-
+    return_state_if_error(r, _ESYS_STATE_INIT, "Initialize session resources");
     iesys_compute_session_value(esysContext->session_tab[0], NULL, NULL);
-    r = iesys_gen_auths(esysContext, NULL, NULL, NULL, &auths);
-    return_if_error(r, "Error in computation of auth values");
+    iesys_compute_session_value(esysContext->session_tab[1], NULL, NULL);
+    iesys_compute_session_value(esysContext->session_tab[2], NULL, NULL);
 
+    /* Generate the auth values and set them in the SAPI command buffer */
+    r = iesys_gen_auths(esysContext, NULL, NULL, NULL, &auths);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Error in computation of auth values");
     esysContext->authsCount = auths.count;
     r = Tss2_Sys_SetCmdAuths(esysContext->sys, &auths);
-    if (r != TSS2_RC_SUCCESS) {
-        return r;
-    }
+    return_state_if_error(r, _ESYS_STATE_INIT, "SAPI error on SetCmdAuths");
 
+    /* Trigger execution and finish the async invocation */
     r = Tss2_Sys_ExecuteAsync(esysContext->sys);
-    return_if_error(r, "Finish (Execute Async)");
+    return_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Finish (Execute Async)");
 
     esysContext->state = _ESYS_STATE_SENT;
 
@@ -195,32 +200,42 @@
     TPM2B_MAX_BUFFER **fuData)
 {
     LOG_TRACE("complete");
+    TSS2_RC r;
     if (esysContext == NULL) {
         LOG_ERROR("esyscontext is NULL.");
         return TSS2_ESYS_RC_BAD_REFERENCE;
     }
+
+    /* Check for correct sequence and set sequence to irregular for now */
     if (esysContext->state != _ESYS_STATE_SENT) {
         LOG_ERROR("Esys called in bad sequence.");
         return TSS2_ESYS_RC_BAD_SEQUENCE;
     }
-    TSS2_RC r;
+    esysContext->state = _ESYS_STATE_INTERNALERROR;
+
+    /* Allocate memory for response parameters */
     if (fuData != NULL) {
         *fuData = calloc(sizeof(TPM2B_MAX_BUFFER), 1);
         if (*fuData == NULL) {
             return_error(TSS2_ESYS_RC_MEMORY, "Out of memory");
         }
     }
+
+    /*Receive the TPM response and handle resubmissions if necessary. */
     r = Tss2_Sys_ExecuteFinish(esysContext->sys, esysContext->timeout);
     if ((r & ~TSS2_RC_LAYER_MASK) == TSS2_BASE_RC_TRY_AGAIN) {
         LOG_DEBUG("A layer below returned TRY_AGAIN: %" PRIx32, r);
+        esysContext->state = _ESYS_STATE_SENT;
         goto error_cleanup;
     }
+    /* This block handle the resubmission of TPM commands given a certain set of
+     * TPM response codes. */
     if (r == TPM2_RC_RETRY || r == TPM2_RC_TESTING || r == TPM2_RC_YIELDED) {
         LOG_DEBUG("TPM returned RETRY, TESTING or YIELDED, which triggers a "
             "resubmission: %" PRIx32, r);
         if (esysContext->submissionCount >= _ESYS_MAX_SUBMISSIONS) {
-            LOG_WARNING("Maximum number of resubmissions has been reached.");
-            esysContext->state = _ESYS_STATE_ERRORRESPONSE;
+            LOG_WARNING("Maximum number of (re)submissions has been reached.");
+            esysContext->state = _ESYS_STATE_INIT;
             goto error_cleanup;
         }
         esysContext->state = _ESYS_STATE_RESUBMISSION;
@@ -230,22 +245,32 @@
                 esysContext->session_type[2],
                 esysContext->in.FirmwareRead.sequenceNumber);
         if (r != TSS2_RC_SUCCESS) {
-            LOG_ERROR("Error attempting to resubmit");
+            LOG_WARNING("Error attempting to resubmit");
+            /* We do not set esysContext->state here but inherit the most recent
+             * state of the _async function. */
             goto error_cleanup;
         }
         r = TSS2_ESYS_RC_TRY_AGAIN;
+        LOG_DEBUG("Resubmission initiated and returning RC_TRY_AGAIN.");
         goto error_cleanup;
     }
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error finish (ExecuteFinish) FirmwareRead");
+    /* The following is the "regular error" handling. */
+    if (r != TSS2_RC_SUCCESS && (r & TSS2_RC_LAYER_MASK) == 0) {
+        LOG_WARNING("Received TPM Error");
+        esysContext->state = _ESYS_STATE_INIT;
+        goto error_cleanup;
+    } else if (r != TSS2_RC_SUCCESS) {
+        LOG_ERROR("Received a non-TPM Error");
+        esysContext->state = _ESYS_STATE_INTERNALERROR;
         goto error_cleanup;
     }
+
     /*
      * Now the verification of the response (hmac check) and if necessary the
-     * parameter decryption have to be done
+     * parameter decryption have to be done.
      */
     r = iesys_check_response(esysContext);
-    goto_if_error(r, "Error: check response",
+    goto_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Error: check response",
                       error_cleanup);
     /*
      * After the verification of the response we call the complete function
@@ -253,17 +278,17 @@
      */
     r = Tss2_Sys_FirmwareRead_Complete(esysContext->sys,
                 (fuData != NULL) ? *fuData : NULL);
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error finish (ExecuteFinish) FirmwareRead: %" PRIx32, r);
-        esysContext->state = _ESYS_STATE_ERRORRESPONSE;
-        goto error_cleanup;;
-    }
-    esysContext->state = _ESYS_STATE_FINISHED;
+    goto_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Received error from SAPI"
+                        " unmarshalling" ,error_cleanup);
+    esysContext->state = _ESYS_STATE_INIT;
+    LOG_DEBUG("context=%p, fuData=%p",
+              esysContext, fuData);
 
-    return r;
+    return TSS2_RC_SUCCESS;
 
 error_cleanup:
     if (fuData != NULL)
         SAFE_FREE(*fuData);
+
     return r;
 }
diff --git a/src/tss2-esys/api/Esys_FlushContext.c b/src/tss2-esys/api/Esys_FlushContext.c
index adc0b99..b84255c 100644
--- a/src/tss2-esys/api/Esys_FlushContext.c
+++ b/src/tss2-esys/api/Esys_FlushContext.c
@@ -119,6 +119,7 @@
     TSS2_RC r;
     RSRC_NODE_T *flushHandleNode;
 
+    /* Check context, sequence correctness and set state to error for now */
     if (esysContext == NULL) {
         LOG_ERROR("esyscontext is NULL.");
         return TSS2_ESYS_RC_BAD_REFERENCE;
@@ -126,19 +127,20 @@
     r = iesys_check_sequence_async(esysContext);
     if (r != TSS2_RC_SUCCESS)
         return r;
-
+    esysContext->state = _ESYS_STATE_INTERNALERROR;
     store_input_parameters(esysContext, flushHandle);
+
+    /* Retrieve the metadata objects for provided handles */
     r = esys_GetResourceObject(esysContext, flushHandle, &flushHandleNode);
-    if (r != TPM2_RC_SUCCESS)
-        return r;
+    return_state_if_error(r, _ESYS_STATE_INIT, "flushHandle unknown.");
+
+    /* Initial invocation of SAPI to prepare the command buffer with parameters */
     r = Tss2_Sys_FlushContext_Prepare(esysContext->sys,
                 (flushHandleNode == NULL) ? TPM2_RH_NULL : flushHandleNode->rsrc.handle);
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error async FlushContext");
-        return r;
-    }
+    return_state_if_error(r, _ESYS_STATE_INIT, "SAPI Prepare returned error.");
+    /* Trigger execution and finish the async invocation */
     r = Tss2_Sys_ExecuteAsync(esysContext->sys);
-    return_if_error(r, "Finish (Execute Async)");
+    return_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Finish (Execute Async)");
 
     esysContext->state = _ESYS_STATE_SENT;
 
@@ -162,53 +164,69 @@
     ESYS_CONTEXT *esysContext)
 {
     LOG_TRACE("complete");
+    TSS2_RC r;
     if (esysContext == NULL) {
         LOG_ERROR("esyscontext is NULL.");
         return TSS2_ESYS_RC_BAD_REFERENCE;
     }
+
+    /* Check for correct sequence and set sequence to irregular for now */
     if (esysContext->state != _ESYS_STATE_SENT) {
         LOG_ERROR("Esys called in bad sequence.");
         return TSS2_ESYS_RC_BAD_SEQUENCE;
     }
-    TSS2_RC r;
+    esysContext->state = _ESYS_STATE_INTERNALERROR;
+
+    /*Receive the TPM response and handle resubmissions if necessary. */
     r = Tss2_Sys_ExecuteFinish(esysContext->sys, esysContext->timeout);
     if ((r & ~TSS2_RC_LAYER_MASK) == TSS2_BASE_RC_TRY_AGAIN) {
         LOG_DEBUG("A layer below returned TRY_AGAIN: %" PRIx32, r);
+        esysContext->state = _ESYS_STATE_SENT;
         return r;
     }
+    /* This block handle the resubmission of TPM commands given a certain set of
+     * TPM response codes. */
     if (r == TPM2_RC_RETRY || r == TPM2_RC_TESTING || r == TPM2_RC_YIELDED) {
         LOG_DEBUG("TPM returned RETRY, TESTING or YIELDED, which triggers a "
             "resubmission: %" PRIx32, r);
         if (esysContext->submissionCount >= _ESYS_MAX_SUBMISSIONS) {
-            LOG_WARNING("Maximum number of resubmissions has been reached.");
-            esysContext->state = _ESYS_STATE_ERRORRESPONSE;
+            LOG_WARNING("Maximum number of (re)submissions has been reached.");
+            esysContext->state = _ESYS_STATE_INIT;
             return r;
         }
         esysContext->state = _ESYS_STATE_RESUBMISSION;
         r = Esys_FlushContext_async(esysContext,
                 esysContext->in.FlushContext.flushHandle);
         if (r != TSS2_RC_SUCCESS) {
-            LOG_ERROR("Error attempting to resubmit");
+            LOG_WARNING("Error attempting to resubmit");
+            /* We do not set esysContext->state here but inherit the most recent
+             * state of the _async function. */
             return r;
         }
         r = TSS2_ESYS_RC_TRY_AGAIN;
+        LOG_DEBUG("Resubmission initiated and returning RC_TRY_AGAIN.");
         return r;
     }
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error finish (ExecuteFinish) FlushContext");
+    /* The following is the "regular error" handling. */
+    if (r != TSS2_RC_SUCCESS && (r & TSS2_RC_LAYER_MASK) == 0) {
+        LOG_WARNING("Received TPM Error");
+        esysContext->state = _ESYS_STATE_INIT;
+        return r;
+    } else if (r != TSS2_RC_SUCCESS) {
+        LOG_ERROR("Received a non-TPM Error");
+        esysContext->state = _ESYS_STATE_INTERNALERROR;
         return r;
     }
     r = Tss2_Sys_FlushContext_Complete(esysContext->sys);
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error finish (ExecuteFinish) FlushContext: %" PRIx32, r);
-        esysContext->state = _ESYS_STATE_ERRORRESPONSE;
-        return r;;
-    }
+    return_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Received error from SAPI"
+                        " unmarshalling" );
     /* The ESYS_TR object has to be invalidated */
     r = Esys_TR_Close(esysContext, &esysContext->in.FlushContext.flushHandle);
     return_if_error(r, "invalidate object");
 
-    esysContext->state = _ESYS_STATE_FINISHED;
+    esysContext->state = _ESYS_STATE_INIT;
+    LOG_DEBUG("context=%p",
+              esysContext);
 
-    return r;
+    return TSS2_RC_SUCCESS;
 }
diff --git a/src/tss2-esys/api/Esys_GetCapability.c b/src/tss2-esys/api/Esys_GetCapability.c
index fec4eef..a087f18 100644
--- a/src/tss2-esys/api/Esys_GetCapability.c
+++ b/src/tss2-esys/api/Esys_GetCapability.c
@@ -154,6 +154,7 @@
     TSS2_RC r;
     TSS2L_SYS_AUTH_COMMAND auths;
 
+    /* Check context, sequence correctness and set state to error for now */
     if (esysContext == NULL) {
         LOG_ERROR("esyscontext is NULL.");
         return TSS2_ESYS_RC_BAD_REFERENCE;
@@ -161,38 +162,40 @@
     r = iesys_check_sequence_async(esysContext);
     if (r != TSS2_RC_SUCCESS)
         return r;
-    r = check_session_feasability(shandle1, shandle2, shandle3, 0);
-    return_if_error(r, "Check session usage");
+    esysContext->state = _ESYS_STATE_INTERNALERROR;
 
+    /* Check and store input parameters */
+    r = check_session_feasability(shandle1, shandle2, shandle3, 0);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Check session usage");
     store_input_parameters(esysContext,
                 capability,
                 property,
                 propertyCount);
+
+    /* Initial invocation of SAPI to prepare the command buffer with parameters */
     r = Tss2_Sys_GetCapability_Prepare(esysContext->sys,
                 capability,
                 property,
                 propertyCount);
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error async GetCapability");
-        return r;
-    }
-    r = init_session_tab(esysContext, shandle1, shandle2, shandle3);
-    return_if_error(r, "Initialize session resources");
+    return_state_if_error(r, _ESYS_STATE_INIT, "SAPI Prepare returned error.");
 
+    /* Calculate the cpHash Values */
+    r = init_session_tab(esysContext, shandle1, shandle2, shandle3);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Initialize session resources");
     iesys_compute_session_value(esysContext->session_tab[0], NULL, NULL);
     iesys_compute_session_value(esysContext->session_tab[1], NULL, NULL);
     iesys_compute_session_value(esysContext->session_tab[2], NULL, NULL);
-    r = iesys_gen_auths(esysContext, NULL, NULL, NULL, &auths);
-    return_if_error(r, "Error in computation of auth values");
 
+    /* Generate the auth values and set them in the SAPI command buffer */
+    r = iesys_gen_auths(esysContext, NULL, NULL, NULL, &auths);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Error in computation of auth values");
     esysContext->authsCount = auths.count;
     r = Tss2_Sys_SetCmdAuths(esysContext->sys, &auths);
-    if (r != TSS2_RC_SUCCESS) {
-        return r;
-    }
+    return_state_if_error(r, _ESYS_STATE_INIT, "SAPI error on SetCmdAuths");
 
+    /* Trigger execution and finish the async invocation */
     r = Tss2_Sys_ExecuteAsync(esysContext->sys);
-    return_if_error(r, "Finish (Execute Async)");
+    return_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Finish (Execute Async)");
 
     esysContext->state = _ESYS_STATE_SENT;
 
@@ -222,32 +225,42 @@
     TPMS_CAPABILITY_DATA **capabilityData)
 {
     LOG_TRACE("complete");
+    TSS2_RC r;
     if (esysContext == NULL) {
         LOG_ERROR("esyscontext is NULL.");
         return TSS2_ESYS_RC_BAD_REFERENCE;
     }
+
+    /* Check for correct sequence and set sequence to irregular for now */
     if (esysContext->state != _ESYS_STATE_SENT) {
         LOG_ERROR("Esys called in bad sequence.");
         return TSS2_ESYS_RC_BAD_SEQUENCE;
     }
-    TSS2_RC r;
+    esysContext->state = _ESYS_STATE_INTERNALERROR;
+
+    /* Allocate memory for response parameters */
     if (capabilityData != NULL) {
         *capabilityData = calloc(sizeof(TPMS_CAPABILITY_DATA), 1);
         if (*capabilityData == NULL) {
             return_error(TSS2_ESYS_RC_MEMORY, "Out of memory");
         }
     }
+
+    /*Receive the TPM response and handle resubmissions if necessary. */
     r = Tss2_Sys_ExecuteFinish(esysContext->sys, esysContext->timeout);
     if ((r & ~TSS2_RC_LAYER_MASK) == TSS2_BASE_RC_TRY_AGAIN) {
         LOG_DEBUG("A layer below returned TRY_AGAIN: %" PRIx32, r);
+        esysContext->state = _ESYS_STATE_SENT;
         goto error_cleanup;
     }
+    /* This block handle the resubmission of TPM commands given a certain set of
+     * TPM response codes. */
     if (r == TPM2_RC_RETRY || r == TPM2_RC_TESTING || r == TPM2_RC_YIELDED) {
         LOG_DEBUG("TPM returned RETRY, TESTING or YIELDED, which triggers a "
             "resubmission: %" PRIx32, r);
         if (esysContext->submissionCount >= _ESYS_MAX_SUBMISSIONS) {
-            LOG_WARNING("Maximum number of resubmissions has been reached.");
-            esysContext->state = _ESYS_STATE_ERRORRESPONSE;
+            LOG_WARNING("Maximum number of (re)submissions has been reached.");
+            esysContext->state = _ESYS_STATE_INIT;
             goto error_cleanup;
         }
         esysContext->state = _ESYS_STATE_RESUBMISSION;
@@ -259,22 +272,32 @@
                 esysContext->in.GetCapability.property,
                 esysContext->in.GetCapability.propertyCount);
         if (r != TSS2_RC_SUCCESS) {
-            LOG_ERROR("Error attempting to resubmit");
+            LOG_WARNING("Error attempting to resubmit");
+            /* We do not set esysContext->state here but inherit the most recent
+             * state of the _async function. */
             goto error_cleanup;
         }
         r = TSS2_ESYS_RC_TRY_AGAIN;
+        LOG_DEBUG("Resubmission initiated and returning RC_TRY_AGAIN.");
         goto error_cleanup;
     }
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error finish (ExecuteFinish) GetCapability");
+    /* The following is the "regular error" handling. */
+    if (r != TSS2_RC_SUCCESS && (r & TSS2_RC_LAYER_MASK) == 0) {
+        LOG_WARNING("Received TPM Error");
+        esysContext->state = _ESYS_STATE_INIT;
+        goto error_cleanup;
+    } else if (r != TSS2_RC_SUCCESS) {
+        LOG_ERROR("Received a non-TPM Error");
+        esysContext->state = _ESYS_STATE_INTERNALERROR;
         goto error_cleanup;
     }
+
     /*
      * Now the verification of the response (hmac check) and if necessary the
-     * parameter decryption have to be done
+     * parameter decryption have to be done.
      */
     r = iesys_check_response(esysContext);
-    goto_if_error(r, "Error: check response",
+    goto_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Error: check response",
                       error_cleanup);
     /*
      * After the verification of the response we call the complete function
@@ -283,17 +306,17 @@
     r = Tss2_Sys_GetCapability_Complete(esysContext->sys,
                 moreData,
                 (capabilityData != NULL) ? *capabilityData : NULL);
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error finish (ExecuteFinish) GetCapability: %" PRIx32, r);
-        esysContext->state = _ESYS_STATE_ERRORRESPONSE;
-        goto error_cleanup;;
-    }
-    esysContext->state = _ESYS_STATE_FINISHED;
+    goto_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Received error from SAPI"
+                        " unmarshalling" ,error_cleanup);
+    esysContext->state = _ESYS_STATE_INIT;
+    LOG_DEBUG("context=%p, moreData=%p, capabilityData=%p",
+              esysContext, moreData, capabilityData);
 
-    return r;
+    return TSS2_RC_SUCCESS;
 
 error_cleanup:
     if (capabilityData != NULL)
         SAFE_FREE(*capabilityData);
+
     return r;
 }
diff --git a/src/tss2-esys/api/Esys_GetCommandAuditDigest.c b/src/tss2-esys/api/Esys_GetCommandAuditDigest.c
index fa576c2..45724a0 100644
--- a/src/tss2-esys/api/Esys_GetCommandAuditDigest.c
+++ b/src/tss2-esys/api/Esys_GetCommandAuditDigest.c
@@ -179,6 +179,7 @@
     RSRC_NODE_T *privacyHandleNode;
     RSRC_NODE_T *signHandleNode;
 
+    /* Check context, sequence correctness and set state to error for now */
     if (esysContext == NULL) {
         LOG_ERROR("esyscontext is NULL.");
         return TSS2_ESYS_RC_BAD_REFERENCE;
@@ -186,46 +187,48 @@
     r = iesys_check_sequence_async(esysContext);
     if (r != TSS2_RC_SUCCESS)
         return r;
-    r = check_session_feasability(shandle1, shandle2, shandle3, 1);
-    return_if_error(r, "Check session usage");
+    esysContext->state = _ESYS_STATE_INTERNALERROR;
 
+    /* Check and store input parameters */
+    r = check_session_feasability(shandle1, shandle2, shandle3, 1);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Check session usage");
     store_input_parameters(esysContext, privacyHandle, signHandle,
                 qualifyingData,
                 inScheme);
+
+    /* Retrieve the metadata objects for provided handles */
     r = esys_GetResourceObject(esysContext, privacyHandle, &privacyHandleNode);
-    if (r != TPM2_RC_SUCCESS)
-        return r;
+    return_state_if_error(r, _ESYS_STATE_INIT, "privacyHandle unknown.");
     r = esys_GetResourceObject(esysContext, signHandle, &signHandleNode);
-    if (r != TPM2_RC_SUCCESS)
-        return r;
+    return_state_if_error(r, _ESYS_STATE_INIT, "signHandle unknown.");
+
+    /* Initial invocation of SAPI to prepare the command buffer with parameters */
     r = Tss2_Sys_GetCommandAuditDigest_Prepare(esysContext->sys,
                 (privacyHandleNode == NULL) ? TPM2_RH_NULL : privacyHandleNode->rsrc.handle,
                 (signHandleNode == NULL) ? TPM2_RH_NULL : signHandleNode->rsrc.handle,
                 qualifyingData,
                 inScheme);
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error async GetCommandAuditDigest");
-        return r;
-    }
-    r = init_session_tab(esysContext, shandle1, shandle2, shandle3);
-    return_if_error(r, "Initialize session resources");
+    return_state_if_error(r, _ESYS_STATE_INIT, "SAPI Prepare returned error.");
 
+    /* Calculate the cpHash Values */
+    r = init_session_tab(esysContext, shandle1, shandle2, shandle3);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Initialize session resources");
     iesys_compute_session_value(esysContext->session_tab[0],
                 &privacyHandleNode->rsrc.name, &privacyHandleNode->auth);
     iesys_compute_session_value(esysContext->session_tab[1],
                 &signHandleNode->rsrc.name, &signHandleNode->auth);
     iesys_compute_session_value(esysContext->session_tab[2], NULL, NULL);
-    r = iesys_gen_auths(esysContext, privacyHandleNode, signHandleNode, NULL, &auths);
-    return_if_error(r, "Error in computation of auth values");
 
+    /* Generate the auth values and set them in the SAPI command buffer */
+    r = iesys_gen_auths(esysContext, privacyHandleNode, signHandleNode, NULL, &auths);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Error in computation of auth values");
     esysContext->authsCount = auths.count;
     r = Tss2_Sys_SetCmdAuths(esysContext->sys, &auths);
-    if (r != TSS2_RC_SUCCESS) {
-        return r;
-    }
+    return_state_if_error(r, _ESYS_STATE_INIT, "SAPI error on SetCmdAuths");
 
+    /* Trigger execution and finish the async invocation */
     r = Tss2_Sys_ExecuteAsync(esysContext->sys);
-    return_if_error(r, "Finish (Execute Async)");
+    return_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Finish (Execute Async)");
 
     esysContext->state = _ESYS_STATE_SENT;
 
@@ -255,15 +258,20 @@
     TPMT_SIGNATURE **signature)
 {
     LOG_TRACE("complete");
+    TSS2_RC r;
     if (esysContext == NULL) {
         LOG_ERROR("esyscontext is NULL.");
         return TSS2_ESYS_RC_BAD_REFERENCE;
     }
+
+    /* Check for correct sequence and set sequence to irregular for now */
     if (esysContext->state != _ESYS_STATE_SENT) {
         LOG_ERROR("Esys called in bad sequence.");
         return TSS2_ESYS_RC_BAD_SEQUENCE;
     }
-    TSS2_RC r;
+    esysContext->state = _ESYS_STATE_INTERNALERROR;
+
+    /* Allocate memory for response parameters */
     if (auditInfo != NULL) {
         *auditInfo = calloc(sizeof(TPM2B_ATTEST), 1);
         if (*auditInfo == NULL) {
@@ -276,17 +284,22 @@
             goto_error(r, TSS2_ESYS_RC_MEMORY, "Out of memory", error_cleanup);
         }
     }
+
+    /*Receive the TPM response and handle resubmissions if necessary. */
     r = Tss2_Sys_ExecuteFinish(esysContext->sys, esysContext->timeout);
     if ((r & ~TSS2_RC_LAYER_MASK) == TSS2_BASE_RC_TRY_AGAIN) {
         LOG_DEBUG("A layer below returned TRY_AGAIN: %" PRIx32, r);
+        esysContext->state = _ESYS_STATE_SENT;
         goto error_cleanup;
     }
+    /* This block handle the resubmission of TPM commands given a certain set of
+     * TPM response codes. */
     if (r == TPM2_RC_RETRY || r == TPM2_RC_TESTING || r == TPM2_RC_YIELDED) {
         LOG_DEBUG("TPM returned RETRY, TESTING or YIELDED, which triggers a "
             "resubmission: %" PRIx32, r);
         if (esysContext->submissionCount >= _ESYS_MAX_SUBMISSIONS) {
-            LOG_WARNING("Maximum number of resubmissions has been reached.");
-            esysContext->state = _ESYS_STATE_ERRORRESPONSE;
+            LOG_WARNING("Maximum number of (re)submissions has been reached.");
+            esysContext->state = _ESYS_STATE_INIT;
             goto error_cleanup;
         }
         esysContext->state = _ESYS_STATE_RESUBMISSION;
@@ -299,22 +312,32 @@
                 esysContext->in.GetCommandAuditDigest.qualifyingData,
                 esysContext->in.GetCommandAuditDigest.inScheme);
         if (r != TSS2_RC_SUCCESS) {
-            LOG_ERROR("Error attempting to resubmit");
+            LOG_WARNING("Error attempting to resubmit");
+            /* We do not set esysContext->state here but inherit the most recent
+             * state of the _async function. */
             goto error_cleanup;
         }
         r = TSS2_ESYS_RC_TRY_AGAIN;
+        LOG_DEBUG("Resubmission initiated and returning RC_TRY_AGAIN.");
         goto error_cleanup;
     }
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error finish (ExecuteFinish) GetCommandAuditDigest");
+    /* The following is the "regular error" handling. */
+    if (r != TSS2_RC_SUCCESS && (r & TSS2_RC_LAYER_MASK) == 0) {
+        LOG_WARNING("Received TPM Error");
+        esysContext->state = _ESYS_STATE_INIT;
+        goto error_cleanup;
+    } else if (r != TSS2_RC_SUCCESS) {
+        LOG_ERROR("Received a non-TPM Error");
+        esysContext->state = _ESYS_STATE_INTERNALERROR;
         goto error_cleanup;
     }
+
     /*
      * Now the verification of the response (hmac check) and if necessary the
-     * parameter decryption have to be done
+     * parameter decryption have to be done.
      */
     r = iesys_check_response(esysContext);
-    goto_if_error(r, "Error: check response",
+    goto_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Error: check response",
                       error_cleanup);
     /*
      * After the verification of the response we call the complete function
@@ -323,19 +346,19 @@
     r = Tss2_Sys_GetCommandAuditDigest_Complete(esysContext->sys,
                 (auditInfo != NULL) ? *auditInfo : NULL,
                 (signature != NULL) ? *signature : NULL);
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error finish (ExecuteFinish) GetCommandAuditDigest: %" PRIx32, r);
-        esysContext->state = _ESYS_STATE_ERRORRESPONSE;
-        goto error_cleanup;;
-    }
-    esysContext->state = _ESYS_STATE_FINISHED;
+    goto_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Received error from SAPI"
+                        " unmarshalling" ,error_cleanup);
+    esysContext->state = _ESYS_STATE_INIT;
+    LOG_DEBUG("context=%p, auditInfo=%p, signature=%p",
+              esysContext, auditInfo, signature);
 
-    return r;
+    return TSS2_RC_SUCCESS;
 
 error_cleanup:
     if (auditInfo != NULL)
         SAFE_FREE(*auditInfo);
     if (signature != NULL)
         SAFE_FREE(*signature);
+
     return r;
 }
diff --git a/src/tss2-esys/api/Esys_GetRandom.c b/src/tss2-esys/api/Esys_GetRandom.c
index 74e27a1..eafdc5e 100644
--- a/src/tss2-esys/api/Esys_GetRandom.c
+++ b/src/tss2-esys/api/Esys_GetRandom.c
@@ -136,6 +136,7 @@
     TSS2_RC r;
     TSS2L_SYS_AUTH_COMMAND auths;
 
+    /* Check context, sequence correctness and set state to error for now */
     if (esysContext == NULL) {
         LOG_ERROR("esyscontext is NULL.");
         return TSS2_ESYS_RC_BAD_REFERENCE;
@@ -143,32 +144,36 @@
     r = iesys_check_sequence_async(esysContext);
     if (r != TSS2_RC_SUCCESS)
         return r;
-    r = check_session_feasability(shandle1, shandle2, shandle3, 0);
-    return_if_error(r, "Check session usage");
+    esysContext->state = _ESYS_STATE_INTERNALERROR;
 
+    /* Check and store input parameters */
+    r = check_session_feasability(shandle1, shandle2, shandle3, 0);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Check session usage");
     store_input_parameters(esysContext,
                 bytesRequested);
+
+    /* Initial invocation of SAPI to prepare the command buffer with parameters */
     r = Tss2_Sys_GetRandom_Prepare(esysContext->sys,
                 bytesRequested);
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error async GetRandom");
-        return r;
-    }
+    return_state_if_error(r, _ESYS_STATE_INIT, "SAPI Prepare returned error.");
+
+    /* Calculate the cpHash Values */
     r = init_session_tab(esysContext, shandle1, shandle2, shandle3);
-    return_if_error(r, "Initialize session resources");
-
+    return_state_if_error(r, _ESYS_STATE_INIT, "Initialize session resources");
     iesys_compute_session_value(esysContext->session_tab[0], NULL, NULL);
-    r = iesys_gen_auths(esysContext, NULL, NULL, NULL, &auths);
-    return_if_error(r, "Error in computation of auth values");
+    iesys_compute_session_value(esysContext->session_tab[1], NULL, NULL);
+    iesys_compute_session_value(esysContext->session_tab[2], NULL, NULL);
 
+    /* Generate the auth values and set them in the SAPI command buffer */
+    r = iesys_gen_auths(esysContext, NULL, NULL, NULL, &auths);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Error in computation of auth values");
     esysContext->authsCount = auths.count;
     r = Tss2_Sys_SetCmdAuths(esysContext->sys, &auths);
-    if (r != TSS2_RC_SUCCESS) {
-        return r;
-    }
+    return_state_if_error(r, _ESYS_STATE_INIT, "SAPI error on SetCmdAuths");
 
+    /* Trigger execution and finish the async invocation */
     r = Tss2_Sys_ExecuteAsync(esysContext->sys);
-    return_if_error(r, "Finish (Execute Async)");
+    return_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Finish (Execute Async)");
 
     esysContext->state = _ESYS_STATE_SENT;
 
@@ -195,32 +200,42 @@
     TPM2B_DIGEST **randomBytes)
 {
     LOG_TRACE("complete");
+    TSS2_RC r;
     if (esysContext == NULL) {
         LOG_ERROR("esyscontext is NULL.");
         return TSS2_ESYS_RC_BAD_REFERENCE;
     }
+
+    /* Check for correct sequence and set sequence to irregular for now */
     if (esysContext->state != _ESYS_STATE_SENT) {
         LOG_ERROR("Esys called in bad sequence.");
         return TSS2_ESYS_RC_BAD_SEQUENCE;
     }
-    TSS2_RC r;
+    esysContext->state = _ESYS_STATE_INTERNALERROR;
+
+    /* Allocate memory for response parameters */
     if (randomBytes != NULL) {
         *randomBytes = calloc(sizeof(TPM2B_DIGEST), 1);
         if (*randomBytes == NULL) {
             return_error(TSS2_ESYS_RC_MEMORY, "Out of memory");
         }
     }
+
+    /*Receive the TPM response and handle resubmissions if necessary. */
     r = Tss2_Sys_ExecuteFinish(esysContext->sys, esysContext->timeout);
     if ((r & ~TSS2_RC_LAYER_MASK) == TSS2_BASE_RC_TRY_AGAIN) {
         LOG_DEBUG("A layer below returned TRY_AGAIN: %" PRIx32, r);
+        esysContext->state = _ESYS_STATE_SENT;
         goto error_cleanup;
     }
+    /* This block handle the resubmission of TPM commands given a certain set of
+     * TPM response codes. */
     if (r == TPM2_RC_RETRY || r == TPM2_RC_TESTING || r == TPM2_RC_YIELDED) {
         LOG_DEBUG("TPM returned RETRY, TESTING or YIELDED, which triggers a "
             "resubmission: %" PRIx32, r);
         if (esysContext->submissionCount >= _ESYS_MAX_SUBMISSIONS) {
-            LOG_WARNING("Maximum number of resubmissions has been reached.");
-            esysContext->state = _ESYS_STATE_ERRORRESPONSE;
+            LOG_WARNING("Maximum number of (re)submissions has been reached.");
+            esysContext->state = _ESYS_STATE_INIT;
             goto error_cleanup;
         }
         esysContext->state = _ESYS_STATE_RESUBMISSION;
@@ -230,22 +245,32 @@
                 esysContext->session_type[2],
                 esysContext->in.GetRandom.bytesRequested);
         if (r != TSS2_RC_SUCCESS) {
-            LOG_ERROR("Error attempting to resubmit");
+            LOG_WARNING("Error attempting to resubmit");
+            /* We do not set esysContext->state here but inherit the most recent
+             * state of the _async function. */
             goto error_cleanup;
         }
         r = TSS2_ESYS_RC_TRY_AGAIN;
+        LOG_DEBUG("Resubmission initiated and returning RC_TRY_AGAIN.");
         goto error_cleanup;
     }
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error finish (ExecuteFinish) GetRandom");
+    /* The following is the "regular error" handling. */
+    if (r != TSS2_RC_SUCCESS && (r & TSS2_RC_LAYER_MASK) == 0) {
+        LOG_WARNING("Received TPM Error");
+        esysContext->state = _ESYS_STATE_INIT;
+        goto error_cleanup;
+    } else if (r != TSS2_RC_SUCCESS) {
+        LOG_ERROR("Received a non-TPM Error");
+        esysContext->state = _ESYS_STATE_INTERNALERROR;
         goto error_cleanup;
     }
+
     /*
      * Now the verification of the response (hmac check) and if necessary the
-     * parameter decryption have to be done
+     * parameter decryption have to be done.
      */
     r = iesys_check_response(esysContext);
-    goto_if_error(r, "Error: check response",
+    goto_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Error: check response",
                       error_cleanup);
     /*
      * After the verification of the response we call the complete function
@@ -253,17 +278,17 @@
      */
     r = Tss2_Sys_GetRandom_Complete(esysContext->sys,
                 (randomBytes != NULL) ? *randomBytes : NULL);
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error finish (ExecuteFinish) GetRandom: %" PRIx32, r);
-        esysContext->state = _ESYS_STATE_ERRORRESPONSE;
-        goto error_cleanup;;
-    }
-    esysContext->state = _ESYS_STATE_FINISHED;
+    goto_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Received error from SAPI"
+                        " unmarshalling" ,error_cleanup);
+    esysContext->state = _ESYS_STATE_INIT;
+    LOG_DEBUG("context=%p, randomBytes=%p",
+              esysContext, randomBytes);
 
-    return r;
+    return TSS2_RC_SUCCESS;
 
 error_cleanup:
     if (randomBytes != NULL)
         SAFE_FREE(*randomBytes);
+
     return r;
 }
diff --git a/src/tss2-esys/api/Esys_GetSessionAuditDigest.c b/src/tss2-esys/api/Esys_GetSessionAuditDigest.c
index ebc2f13..3856f50 100644
--- a/src/tss2-esys/api/Esys_GetSessionAuditDigest.c
+++ b/src/tss2-esys/api/Esys_GetSessionAuditDigest.c
@@ -189,6 +189,7 @@
     RSRC_NODE_T *signHandleNode;
     RSRC_NODE_T *sessionHandleNode;
 
+    /* Check context, sequence correctness and set state to error for now */
     if (esysContext == NULL) {
         LOG_ERROR("esyscontext is NULL.");
         return TSS2_ESYS_RC_BAD_REFERENCE;
@@ -196,50 +197,51 @@
     r = iesys_check_sequence_async(esysContext);
     if (r != TSS2_RC_SUCCESS)
         return r;
-    r = check_session_feasability(shandle1, shandle2, shandle3, 1);
-    return_if_error(r, "Check session usage");
+    esysContext->state = _ESYS_STATE_INTERNALERROR;
 
+    /* Check and store input parameters */
+    r = check_session_feasability(shandle1, shandle2, shandle3, 1);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Check session usage");
     store_input_parameters(esysContext, privacyAdminHandle, signHandle, sessionHandle,
                 qualifyingData,
                 inScheme);
+
+    /* Retrieve the metadata objects for provided handles */
     r = esys_GetResourceObject(esysContext, privacyAdminHandle, &privacyAdminHandleNode);
-    if (r != TPM2_RC_SUCCESS)
-        return r;
+    return_state_if_error(r, _ESYS_STATE_INIT, "privacyAdminHandle unknown.");
     r = esys_GetResourceObject(esysContext, signHandle, &signHandleNode);
-    if (r != TPM2_RC_SUCCESS)
-        return r;
+    return_state_if_error(r, _ESYS_STATE_INIT, "signHandle unknown.");
     r = esys_GetResourceObject(esysContext, sessionHandle, &sessionHandleNode);
-    if (r != TPM2_RC_SUCCESS)
-        return r;
+    return_state_if_error(r, _ESYS_STATE_INIT, "sessionHandle unknown.");
+
+    /* Initial invocation of SAPI to prepare the command buffer with parameters */
     r = Tss2_Sys_GetSessionAuditDigest_Prepare(esysContext->sys,
                 (privacyAdminHandleNode == NULL) ? TPM2_RH_NULL : privacyAdminHandleNode->rsrc.handle,
                 (signHandleNode == NULL) ? TPM2_RH_NULL : signHandleNode->rsrc.handle,
                 (sessionHandleNode == NULL) ? TPM2_RH_NULL : sessionHandleNode->rsrc.handle,
                 qualifyingData,
                 inScheme);
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error async GetSessionAuditDigest");
-        return r;
-    }
-    r = init_session_tab(esysContext, shandle1, shandle2, shandle3);
-    return_if_error(r, "Initialize session resources");
+    return_state_if_error(r, _ESYS_STATE_INIT, "SAPI Prepare returned error.");
 
+    /* Calculate the cpHash Values */
+    r = init_session_tab(esysContext, shandle1, shandle2, shandle3);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Initialize session resources");
     iesys_compute_session_value(esysContext->session_tab[0],
                 &privacyAdminHandleNode->rsrc.name, &privacyAdminHandleNode->auth);
     iesys_compute_session_value(esysContext->session_tab[1],
                 &signHandleNode->rsrc.name, &signHandleNode->auth);
     iesys_compute_session_value(esysContext->session_tab[2], NULL, NULL);
-    r = iesys_gen_auths(esysContext, privacyAdminHandleNode, signHandleNode, sessionHandleNode, &auths);
-    return_if_error(r, "Error in computation of auth values");
 
+    /* Generate the auth values and set them in the SAPI command buffer */
+    r = iesys_gen_auths(esysContext, privacyAdminHandleNode, signHandleNode, sessionHandleNode, &auths);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Error in computation of auth values");
     esysContext->authsCount = auths.count;
     r = Tss2_Sys_SetCmdAuths(esysContext->sys, &auths);
-    if (r != TSS2_RC_SUCCESS) {
-        return r;
-    }
+    return_state_if_error(r, _ESYS_STATE_INIT, "SAPI error on SetCmdAuths");
 
+    /* Trigger execution and finish the async invocation */
     r = Tss2_Sys_ExecuteAsync(esysContext->sys);
-    return_if_error(r, "Finish (Execute Async)");
+    return_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Finish (Execute Async)");
 
     esysContext->state = _ESYS_STATE_SENT;
 
@@ -269,15 +271,20 @@
     TPMT_SIGNATURE **signature)
 {
     LOG_TRACE("complete");
+    TSS2_RC r;
     if (esysContext == NULL) {
         LOG_ERROR("esyscontext is NULL.");
         return TSS2_ESYS_RC_BAD_REFERENCE;
     }
+
+    /* Check for correct sequence and set sequence to irregular for now */
     if (esysContext->state != _ESYS_STATE_SENT) {
         LOG_ERROR("Esys called in bad sequence.");
         return TSS2_ESYS_RC_BAD_SEQUENCE;
     }
-    TSS2_RC r;
+    esysContext->state = _ESYS_STATE_INTERNALERROR;
+
+    /* Allocate memory for response parameters */
     if (auditInfo != NULL) {
         *auditInfo = calloc(sizeof(TPM2B_ATTEST), 1);
         if (*auditInfo == NULL) {
@@ -290,17 +297,22 @@
             goto_error(r, TSS2_ESYS_RC_MEMORY, "Out of memory", error_cleanup);
         }
     }
+
+    /*Receive the TPM response and handle resubmissions if necessary. */
     r = Tss2_Sys_ExecuteFinish(esysContext->sys, esysContext->timeout);
     if ((r & ~TSS2_RC_LAYER_MASK) == TSS2_BASE_RC_TRY_AGAIN) {
         LOG_DEBUG("A layer below returned TRY_AGAIN: %" PRIx32, r);
+        esysContext->state = _ESYS_STATE_SENT;
         goto error_cleanup;
     }
+    /* This block handle the resubmission of TPM commands given a certain set of
+     * TPM response codes. */
     if (r == TPM2_RC_RETRY || r == TPM2_RC_TESTING || r == TPM2_RC_YIELDED) {
         LOG_DEBUG("TPM returned RETRY, TESTING or YIELDED, which triggers a "
             "resubmission: %" PRIx32, r);
         if (esysContext->submissionCount >= _ESYS_MAX_SUBMISSIONS) {
-            LOG_WARNING("Maximum number of resubmissions has been reached.");
-            esysContext->state = _ESYS_STATE_ERRORRESPONSE;
+            LOG_WARNING("Maximum number of (re)submissions has been reached.");
+            esysContext->state = _ESYS_STATE_INIT;
             goto error_cleanup;
         }
         esysContext->state = _ESYS_STATE_RESUBMISSION;
@@ -314,22 +326,32 @@
                 esysContext->in.GetSessionAuditDigest.qualifyingData,
                 esysContext->in.GetSessionAuditDigest.inScheme);
         if (r != TSS2_RC_SUCCESS) {
-            LOG_ERROR("Error attempting to resubmit");
+            LOG_WARNING("Error attempting to resubmit");
+            /* We do not set esysContext->state here but inherit the most recent
+             * state of the _async function. */
             goto error_cleanup;
         }
         r = TSS2_ESYS_RC_TRY_AGAIN;
+        LOG_DEBUG("Resubmission initiated and returning RC_TRY_AGAIN.");
         goto error_cleanup;
     }
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error finish (ExecuteFinish) GetSessionAuditDigest");
+    /* The following is the "regular error" handling. */
+    if (r != TSS2_RC_SUCCESS && (r & TSS2_RC_LAYER_MASK) == 0) {
+        LOG_WARNING("Received TPM Error");
+        esysContext->state = _ESYS_STATE_INIT;
+        goto error_cleanup;
+    } else if (r != TSS2_RC_SUCCESS) {
+        LOG_ERROR("Received a non-TPM Error");
+        esysContext->state = _ESYS_STATE_INTERNALERROR;
         goto error_cleanup;
     }
+
     /*
      * Now the verification of the response (hmac check) and if necessary the
-     * parameter decryption have to be done
+     * parameter decryption have to be done.
      */
     r = iesys_check_response(esysContext);
-    goto_if_error(r, "Error: check response",
+    goto_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Error: check response",
                       error_cleanup);
     /*
      * After the verification of the response we call the complete function
@@ -338,19 +360,19 @@
     r = Tss2_Sys_GetSessionAuditDigest_Complete(esysContext->sys,
                 (auditInfo != NULL) ? *auditInfo : NULL,
                 (signature != NULL) ? *signature : NULL);
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error finish (ExecuteFinish) GetSessionAuditDigest: %" PRIx32, r);
-        esysContext->state = _ESYS_STATE_ERRORRESPONSE;
-        goto error_cleanup;;
-    }
-    esysContext->state = _ESYS_STATE_FINISHED;
+    goto_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Received error from SAPI"
+                        " unmarshalling" ,error_cleanup);
+    esysContext->state = _ESYS_STATE_INIT;
+    LOG_DEBUG("context=%p, auditInfo=%p, signature=%p",
+              esysContext, auditInfo, signature);
 
-    return r;
+    return TSS2_RC_SUCCESS;
 
 error_cleanup:
     if (auditInfo != NULL)
         SAFE_FREE(*auditInfo);
     if (signature != NULL)
         SAFE_FREE(*signature);
+
     return r;
 }
diff --git a/src/tss2-esys/api/Esys_GetTestResult.c b/src/tss2-esys/api/Esys_GetTestResult.c
index 1c698e5..b4d1759 100644
--- a/src/tss2-esys/api/Esys_GetTestResult.c
+++ b/src/tss2-esys/api/Esys_GetTestResult.c
@@ -128,6 +128,7 @@
     TSS2_RC r;
     TSS2L_SYS_AUTH_COMMAND auths;
 
+    /* Check context, sequence correctness and set state to error for now */
     if (esysContext == NULL) {
         LOG_ERROR("esyscontext is NULL.");
         return TSS2_ESYS_RC_BAD_REFERENCE;
@@ -135,27 +136,33 @@
     r = iesys_check_sequence_async(esysContext);
     if (r != TSS2_RC_SUCCESS)
         return r;
+    esysContext->state = _ESYS_STATE_INTERNALERROR;
+
+    /* Check and store input parameters */
     r = check_session_feasability(shandle1, shandle2, shandle3, 0);
-    return_if_error(r, "Check session usage");
+    return_state_if_error(r, _ESYS_STATE_INIT, "Check session usage");
+
+    /* Initial invocation of SAPI to prepare the command buffer with parameters */
     r = Tss2_Sys_GetTestResult_Prepare(esysContext->sys);
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error async GetTestResult");
-        return r;
-    }
+    return_state_if_error(r, _ESYS_STATE_INIT, "SAPI Prepare returned error.");
+
+    /* Calculate the cpHash Values */
     r = init_session_tab(esysContext, shandle1, shandle2, shandle3);
-    return_if_error(r, "Initialize session resources");
+    return_state_if_error(r, _ESYS_STATE_INIT, "Initialize session resources");
+    iesys_compute_session_value(esysContext->session_tab[0], NULL, NULL);
+    iesys_compute_session_value(esysContext->session_tab[1], NULL, NULL);
+    iesys_compute_session_value(esysContext->session_tab[2], NULL, NULL);
 
+    /* Generate the auth values and set them in the SAPI command buffer */
     r = iesys_gen_auths(esysContext, NULL, NULL, NULL, &auths);
-    return_if_error(r, "Error in computation of auth values");
-
+    return_state_if_error(r, _ESYS_STATE_INIT, "Error in computation of auth values");
     esysContext->authsCount = auths.count;
     r = Tss2_Sys_SetCmdAuths(esysContext->sys, &auths);
-    if (r != TSS2_RC_SUCCESS) {
-        return r;
-    }
+    return_state_if_error(r, _ESYS_STATE_INIT, "SAPI error on SetCmdAuths");
 
+    /* Trigger execution and finish the async invocation */
     r = Tss2_Sys_ExecuteAsync(esysContext->sys);
-    return_if_error(r, "Finish (Execute Async)");
+    return_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Finish (Execute Async)");
 
     esysContext->state = _ESYS_STATE_SENT;
 
@@ -185,32 +192,42 @@
     TPM2_RC *testResult)
 {
     LOG_TRACE("complete");
+    TSS2_RC r;
     if (esysContext == NULL) {
         LOG_ERROR("esyscontext is NULL.");
         return TSS2_ESYS_RC_BAD_REFERENCE;
     }
+
+    /* Check for correct sequence and set sequence to irregular for now */
     if (esysContext->state != _ESYS_STATE_SENT) {
         LOG_ERROR("Esys called in bad sequence.");
         return TSS2_ESYS_RC_BAD_SEQUENCE;
     }
-    TSS2_RC r;
+    esysContext->state = _ESYS_STATE_INTERNALERROR;
+
+    /* Allocate memory for response parameters */
     if (outData != NULL) {
         *outData = calloc(sizeof(TPM2B_MAX_BUFFER), 1);
         if (*outData == NULL) {
             return_error(TSS2_ESYS_RC_MEMORY, "Out of memory");
         }
     }
+
+    /*Receive the TPM response and handle resubmissions if necessary. */
     r = Tss2_Sys_ExecuteFinish(esysContext->sys, esysContext->timeout);
     if ((r & ~TSS2_RC_LAYER_MASK) == TSS2_BASE_RC_TRY_AGAIN) {
         LOG_DEBUG("A layer below returned TRY_AGAIN: %" PRIx32, r);
+        esysContext->state = _ESYS_STATE_SENT;
         goto error_cleanup;
     }
+    /* This block handle the resubmission of TPM commands given a certain set of
+     * TPM response codes. */
     if (r == TPM2_RC_RETRY || r == TPM2_RC_TESTING || r == TPM2_RC_YIELDED) {
         LOG_DEBUG("TPM returned RETRY, TESTING or YIELDED, which triggers a "
             "resubmission: %" PRIx32, r);
         if (esysContext->submissionCount >= _ESYS_MAX_SUBMISSIONS) {
-            LOG_WARNING("Maximum number of resubmissions has been reached.");
-            esysContext->state = _ESYS_STATE_ERRORRESPONSE;
+            LOG_WARNING("Maximum number of (re)submissions has been reached.");
+            esysContext->state = _ESYS_STATE_INIT;
             goto error_cleanup;
         }
         esysContext->state = _ESYS_STATE_RESUBMISSION;
@@ -219,22 +236,32 @@
                 esysContext->session_type[1],
                 esysContext->session_type[2]);
         if (r != TSS2_RC_SUCCESS) {
-            LOG_ERROR("Error attempting to resubmit");
+            LOG_WARNING("Error attempting to resubmit");
+            /* We do not set esysContext->state here but inherit the most recent
+             * state of the _async function. */
             goto error_cleanup;
         }
         r = TSS2_ESYS_RC_TRY_AGAIN;
+        LOG_DEBUG("Resubmission initiated and returning RC_TRY_AGAIN.");
         goto error_cleanup;
     }
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error finish (ExecuteFinish) GetTestResult");
+    /* The following is the "regular error" handling. */
+    if (r != TSS2_RC_SUCCESS && (r & TSS2_RC_LAYER_MASK) == 0) {
+        LOG_WARNING("Received TPM Error");
+        esysContext->state = _ESYS_STATE_INIT;
+        goto error_cleanup;
+    } else if (r != TSS2_RC_SUCCESS) {
+        LOG_ERROR("Received a non-TPM Error");
+        esysContext->state = _ESYS_STATE_INTERNALERROR;
         goto error_cleanup;
     }
+
     /*
      * Now the verification of the response (hmac check) and if necessary the
-     * parameter decryption have to be done
+     * parameter decryption have to be done.
      */
     r = iesys_check_response(esysContext);
-    goto_if_error(r, "Error: check response",
+    goto_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Error: check response",
                       error_cleanup);
     /*
      * After the verification of the response we call the complete function
@@ -243,17 +270,17 @@
     r = Tss2_Sys_GetTestResult_Complete(esysContext->sys,
                 (outData != NULL) ? *outData : NULL,
                 testResult);
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error finish (ExecuteFinish) GetTestResult: %" PRIx32, r);
-        esysContext->state = _ESYS_STATE_ERRORRESPONSE;
-        goto error_cleanup;;
-    }
-    esysContext->state = _ESYS_STATE_FINISHED;
+    goto_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Received error from SAPI"
+                        " unmarshalling" ,error_cleanup);
+    esysContext->state = _ESYS_STATE_INIT;
+    LOG_DEBUG("context=%p, outData=%p, testResult=%p",
+              esysContext, outData, testResult);
 
-    return r;
+    return TSS2_RC_SUCCESS;
 
 error_cleanup:
     if (outData != NULL)
         SAFE_FREE(*outData);
+
     return r;
 }
diff --git a/src/tss2-esys/api/Esys_GetTime.c b/src/tss2-esys/api/Esys_GetTime.c
index 59378e6..d40842b 100644
--- a/src/tss2-esys/api/Esys_GetTime.c
+++ b/src/tss2-esys/api/Esys_GetTime.c
@@ -179,6 +179,7 @@
     RSRC_NODE_T *privacyAdminHandleNode;
     RSRC_NODE_T *signHandleNode;
 
+    /* Check context, sequence correctness and set state to error for now */
     if (esysContext == NULL) {
         LOG_ERROR("esyscontext is NULL.");
         return TSS2_ESYS_RC_BAD_REFERENCE;
@@ -186,46 +187,48 @@
     r = iesys_check_sequence_async(esysContext);
     if (r != TSS2_RC_SUCCESS)
         return r;
-    r = check_session_feasability(shandle1, shandle2, shandle3, 1);
-    return_if_error(r, "Check session usage");
+    esysContext->state = _ESYS_STATE_INTERNALERROR;
 
+    /* Check and store input parameters */
+    r = check_session_feasability(shandle1, shandle2, shandle3, 1);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Check session usage");
     store_input_parameters(esysContext, privacyAdminHandle, signHandle,
                 qualifyingData,
                 inScheme);
+
+    /* Retrieve the metadata objects for provided handles */
     r = esys_GetResourceObject(esysContext, privacyAdminHandle, &privacyAdminHandleNode);
-    if (r != TPM2_RC_SUCCESS)
-        return r;
+    return_state_if_error(r, _ESYS_STATE_INIT, "privacyAdminHandle unknown.");
     r = esys_GetResourceObject(esysContext, signHandle, &signHandleNode);
-    if (r != TPM2_RC_SUCCESS)
-        return r;
+    return_state_if_error(r, _ESYS_STATE_INIT, "signHandle unknown.");
+
+    /* Initial invocation of SAPI to prepare the command buffer with parameters */
     r = Tss2_Sys_GetTime_Prepare(esysContext->sys,
                 (privacyAdminHandleNode == NULL) ? TPM2_RH_NULL : privacyAdminHandleNode->rsrc.handle,
                 (signHandleNode == NULL) ? TPM2_RH_NULL : signHandleNode->rsrc.handle,
                 qualifyingData,
                 inScheme);
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error async GetTime");
-        return r;
-    }
-    r = init_session_tab(esysContext, shandle1, shandle2, shandle3);
-    return_if_error(r, "Initialize session resources");
+    return_state_if_error(r, _ESYS_STATE_INIT, "SAPI Prepare returned error.");
 
+    /* Calculate the cpHash Values */
+    r = init_session_tab(esysContext, shandle1, shandle2, shandle3);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Initialize session resources");
     iesys_compute_session_value(esysContext->session_tab[0],
                 &privacyAdminHandleNode->rsrc.name, &privacyAdminHandleNode->auth);
     iesys_compute_session_value(esysContext->session_tab[1],
                 &signHandleNode->rsrc.name, &signHandleNode->auth);
     iesys_compute_session_value(esysContext->session_tab[2], NULL, NULL);
-    r = iesys_gen_auths(esysContext, privacyAdminHandleNode, signHandleNode, NULL, &auths);
-    return_if_error(r, "Error in computation of auth values");
 
+    /* Generate the auth values and set them in the SAPI command buffer */
+    r = iesys_gen_auths(esysContext, privacyAdminHandleNode, signHandleNode, NULL, &auths);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Error in computation of auth values");
     esysContext->authsCount = auths.count;
     r = Tss2_Sys_SetCmdAuths(esysContext->sys, &auths);
-    if (r != TSS2_RC_SUCCESS) {
-        return r;
-    }
+    return_state_if_error(r, _ESYS_STATE_INIT, "SAPI error on SetCmdAuths");
 
+    /* Trigger execution and finish the async invocation */
     r = Tss2_Sys_ExecuteAsync(esysContext->sys);
-    return_if_error(r, "Finish (Execute Async)");
+    return_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Finish (Execute Async)");
 
     esysContext->state = _ESYS_STATE_SENT;
 
@@ -255,15 +258,20 @@
     TPMT_SIGNATURE **signature)
 {
     LOG_TRACE("complete");
+    TSS2_RC r;
     if (esysContext == NULL) {
         LOG_ERROR("esyscontext is NULL.");
         return TSS2_ESYS_RC_BAD_REFERENCE;
     }
+
+    /* Check for correct sequence and set sequence to irregular for now */
     if (esysContext->state != _ESYS_STATE_SENT) {
         LOG_ERROR("Esys called in bad sequence.");
         return TSS2_ESYS_RC_BAD_SEQUENCE;
     }
-    TSS2_RC r;
+    esysContext->state = _ESYS_STATE_INTERNALERROR;
+
+    /* Allocate memory for response parameters */
     if (timeInfo != NULL) {
         *timeInfo = calloc(sizeof(TPM2B_ATTEST), 1);
         if (*timeInfo == NULL) {
@@ -276,17 +284,22 @@
             goto_error(r, TSS2_ESYS_RC_MEMORY, "Out of memory", error_cleanup);
         }
     }
+
+    /*Receive the TPM response and handle resubmissions if necessary. */
     r = Tss2_Sys_ExecuteFinish(esysContext->sys, esysContext->timeout);
     if ((r & ~TSS2_RC_LAYER_MASK) == TSS2_BASE_RC_TRY_AGAIN) {
         LOG_DEBUG("A layer below returned TRY_AGAIN: %" PRIx32, r);
+        esysContext->state = _ESYS_STATE_SENT;
         goto error_cleanup;
     }
+    /* This block handle the resubmission of TPM commands given a certain set of
+     * TPM response codes. */
     if (r == TPM2_RC_RETRY || r == TPM2_RC_TESTING || r == TPM2_RC_YIELDED) {
         LOG_DEBUG("TPM returned RETRY, TESTING or YIELDED, which triggers a "
             "resubmission: %" PRIx32, r);
         if (esysContext->submissionCount >= _ESYS_MAX_SUBMISSIONS) {
-            LOG_WARNING("Maximum number of resubmissions has been reached.");
-            esysContext->state = _ESYS_STATE_ERRORRESPONSE;
+            LOG_WARNING("Maximum number of (re)submissions has been reached.");
+            esysContext->state = _ESYS_STATE_INIT;
             goto error_cleanup;
         }
         esysContext->state = _ESYS_STATE_RESUBMISSION;
@@ -299,22 +312,32 @@
                 esysContext->in.GetTime.qualifyingData,
                 esysContext->in.GetTime.inScheme);
         if (r != TSS2_RC_SUCCESS) {
-            LOG_ERROR("Error attempting to resubmit");
+            LOG_WARNING("Error attempting to resubmit");
+            /* We do not set esysContext->state here but inherit the most recent
+             * state of the _async function. */
             goto error_cleanup;
         }
         r = TSS2_ESYS_RC_TRY_AGAIN;
+        LOG_DEBUG("Resubmission initiated and returning RC_TRY_AGAIN.");
         goto error_cleanup;
     }
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error finish (ExecuteFinish) GetTime");
+    /* The following is the "regular error" handling. */
+    if (r != TSS2_RC_SUCCESS && (r & TSS2_RC_LAYER_MASK) == 0) {
+        LOG_WARNING("Received TPM Error");
+        esysContext->state = _ESYS_STATE_INIT;
+        goto error_cleanup;
+    } else if (r != TSS2_RC_SUCCESS) {
+        LOG_ERROR("Received a non-TPM Error");
+        esysContext->state = _ESYS_STATE_INTERNALERROR;
         goto error_cleanup;
     }
+
     /*
      * Now the verification of the response (hmac check) and if necessary the
-     * parameter decryption have to be done
+     * parameter decryption have to be done.
      */
     r = iesys_check_response(esysContext);
-    goto_if_error(r, "Error: check response",
+    goto_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Error: check response",
                       error_cleanup);
     /*
      * After the verification of the response we call the complete function
@@ -323,19 +346,19 @@
     r = Tss2_Sys_GetTime_Complete(esysContext->sys,
                 (timeInfo != NULL) ? *timeInfo : NULL,
                 (signature != NULL) ? *signature : NULL);
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error finish (ExecuteFinish) GetTime: %" PRIx32, r);
-        esysContext->state = _ESYS_STATE_ERRORRESPONSE;
-        goto error_cleanup;;
-    }
-    esysContext->state = _ESYS_STATE_FINISHED;
+    goto_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Received error from SAPI"
+                        " unmarshalling" ,error_cleanup);
+    esysContext->state = _ESYS_STATE_INIT;
+    LOG_DEBUG("context=%p, timeInfo=%p, signature=%p",
+              esysContext, timeInfo, signature);
 
-    return r;
+    return TSS2_RC_SUCCESS;
 
 error_cleanup:
     if (timeInfo != NULL)
         SAFE_FREE(*timeInfo);
     if (signature != NULL)
         SAFE_FREE(*signature);
+
     return r;
 }
diff --git a/src/tss2-esys/api/Esys_HMAC.c b/src/tss2-esys/api/Esys_HMAC.c
index c3c7f2e..df8838b 100644
--- a/src/tss2-esys/api/Esys_HMAC.c
+++ b/src/tss2-esys/api/Esys_HMAC.c
@@ -159,6 +159,7 @@
     TSS2L_SYS_AUTH_COMMAND auths;
     RSRC_NODE_T *handleNode;
 
+    /* Check context, sequence correctness and set state to error for now */
     if (esysContext == NULL) {
         LOG_ERROR("esyscontext is NULL.");
         return TSS2_ESYS_RC_BAD_REFERENCE;
@@ -166,41 +167,44 @@
     r = iesys_check_sequence_async(esysContext);
     if (r != TSS2_RC_SUCCESS)
         return r;
-    r = check_session_feasability(shandle1, shandle2, shandle3, 1);
-    return_if_error(r, "Check session usage");
+    esysContext->state = _ESYS_STATE_INTERNALERROR;
 
+    /* Check and store input parameters */
+    r = check_session_feasability(shandle1, shandle2, shandle3, 1);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Check session usage");
     store_input_parameters(esysContext, handle,
                 buffer,
                 hashAlg);
+
+    /* Retrieve the metadata objects for provided handles */
     r = esys_GetResourceObject(esysContext, handle, &handleNode);
-    if (r != TPM2_RC_SUCCESS)
-        return r;
+    return_state_if_error(r, _ESYS_STATE_INIT, "handle unknown.");
+
+    /* Initial invocation of SAPI to prepare the command buffer with parameters */
     r = Tss2_Sys_HMAC_Prepare(esysContext->sys,
                 (handleNode == NULL) ? TPM2_RH_NULL : handleNode->rsrc.handle,
                 buffer,
                 hashAlg);
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error async HMAC");
-        return r;
-    }
-    r = init_session_tab(esysContext, shandle1, shandle2, shandle3);
-    return_if_error(r, "Initialize session resources");
+    return_state_if_error(r, _ESYS_STATE_INIT, "SAPI Prepare returned error.");
 
+    /* Calculate the cpHash Values */
+    r = init_session_tab(esysContext, shandle1, shandle2, shandle3);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Initialize session resources");
     iesys_compute_session_value(esysContext->session_tab[0],
                 &handleNode->rsrc.name, &handleNode->auth);
     iesys_compute_session_value(esysContext->session_tab[1], NULL, NULL);
     iesys_compute_session_value(esysContext->session_tab[2], NULL, NULL);
-    r = iesys_gen_auths(esysContext, handleNode, NULL, NULL, &auths);
-    return_if_error(r, "Error in computation of auth values");
 
+    /* Generate the auth values and set them in the SAPI command buffer */
+    r = iesys_gen_auths(esysContext, handleNode, NULL, NULL, &auths);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Error in computation of auth values");
     esysContext->authsCount = auths.count;
     r = Tss2_Sys_SetCmdAuths(esysContext->sys, &auths);
-    if (r != TSS2_RC_SUCCESS) {
-        return r;
-    }
+    return_state_if_error(r, _ESYS_STATE_INIT, "SAPI error on SetCmdAuths");
 
+    /* Trigger execution and finish the async invocation */
     r = Tss2_Sys_ExecuteAsync(esysContext->sys);
-    return_if_error(r, "Finish (Execute Async)");
+    return_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Finish (Execute Async)");
 
     esysContext->state = _ESYS_STATE_SENT;
 
@@ -227,32 +231,42 @@
     TPM2B_DIGEST **outHMAC)
 {
     LOG_TRACE("complete");
+    TSS2_RC r;
     if (esysContext == NULL) {
         LOG_ERROR("esyscontext is NULL.");
         return TSS2_ESYS_RC_BAD_REFERENCE;
     }
+
+    /* Check for correct sequence and set sequence to irregular for now */
     if (esysContext->state != _ESYS_STATE_SENT) {
         LOG_ERROR("Esys called in bad sequence.");
         return TSS2_ESYS_RC_BAD_SEQUENCE;
     }
-    TSS2_RC r;
+    esysContext->state = _ESYS_STATE_INTERNALERROR;
+
+    /* Allocate memory for response parameters */
     if (outHMAC != NULL) {
         *outHMAC = calloc(sizeof(TPM2B_DIGEST), 1);
         if (*outHMAC == NULL) {
             return_error(TSS2_ESYS_RC_MEMORY, "Out of memory");
         }
     }
+
+    /*Receive the TPM response and handle resubmissions if necessary. */
     r = Tss2_Sys_ExecuteFinish(esysContext->sys, esysContext->timeout);
     if ((r & ~TSS2_RC_LAYER_MASK) == TSS2_BASE_RC_TRY_AGAIN) {
         LOG_DEBUG("A layer below returned TRY_AGAIN: %" PRIx32, r);
+        esysContext->state = _ESYS_STATE_SENT;
         goto error_cleanup;
     }
+    /* This block handle the resubmission of TPM commands given a certain set of
+     * TPM response codes. */
     if (r == TPM2_RC_RETRY || r == TPM2_RC_TESTING || r == TPM2_RC_YIELDED) {
         LOG_DEBUG("TPM returned RETRY, TESTING or YIELDED, which triggers a "
             "resubmission: %" PRIx32, r);
         if (esysContext->submissionCount >= _ESYS_MAX_SUBMISSIONS) {
-            LOG_WARNING("Maximum number of resubmissions has been reached.");
-            esysContext->state = _ESYS_STATE_ERRORRESPONSE;
+            LOG_WARNING("Maximum number of (re)submissions has been reached.");
+            esysContext->state = _ESYS_STATE_INIT;
             goto error_cleanup;
         }
         esysContext->state = _ESYS_STATE_RESUBMISSION;
@@ -264,22 +278,32 @@
                 esysContext->in.HMAC.buffer,
                 esysContext->in.HMAC.hashAlg);
         if (r != TSS2_RC_SUCCESS) {
-            LOG_ERROR("Error attempting to resubmit");
+            LOG_WARNING("Error attempting to resubmit");
+            /* We do not set esysContext->state here but inherit the most recent
+             * state of the _async function. */
             goto error_cleanup;
         }
         r = TSS2_ESYS_RC_TRY_AGAIN;
+        LOG_DEBUG("Resubmission initiated and returning RC_TRY_AGAIN.");
         goto error_cleanup;
     }
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error finish (ExecuteFinish) HMAC");
+    /* The following is the "regular error" handling. */
+    if (r != TSS2_RC_SUCCESS && (r & TSS2_RC_LAYER_MASK) == 0) {
+        LOG_WARNING("Received TPM Error");
+        esysContext->state = _ESYS_STATE_INIT;
+        goto error_cleanup;
+    } else if (r != TSS2_RC_SUCCESS) {
+        LOG_ERROR("Received a non-TPM Error");
+        esysContext->state = _ESYS_STATE_INTERNALERROR;
         goto error_cleanup;
     }
+
     /*
      * Now the verification of the response (hmac check) and if necessary the
-     * parameter decryption have to be done
+     * parameter decryption have to be done.
      */
     r = iesys_check_response(esysContext);
-    goto_if_error(r, "Error: check response",
+    goto_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Error: check response",
                       error_cleanup);
     /*
      * After the verification of the response we call the complete function
@@ -287,17 +311,17 @@
      */
     r = Tss2_Sys_HMAC_Complete(esysContext->sys,
                 (outHMAC != NULL) ? *outHMAC : NULL);
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error finish (ExecuteFinish) HMAC: %" PRIx32, r);
-        esysContext->state = _ESYS_STATE_ERRORRESPONSE;
-        goto error_cleanup;;
-    }
-    esysContext->state = _ESYS_STATE_FINISHED;
+    goto_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Received error from SAPI"
+                        " unmarshalling" ,error_cleanup);
+    esysContext->state = _ESYS_STATE_INIT;
+    LOG_DEBUG("context=%p, outHMAC=%p",
+              esysContext, outHMAC);
 
-    return r;
+    return TSS2_RC_SUCCESS;
 
 error_cleanup:
     if (outHMAC != NULL)
         SAFE_FREE(*outHMAC);
+
     return r;
 }
diff --git a/src/tss2-esys/api/Esys_HMAC_Start.c b/src/tss2-esys/api/Esys_HMAC_Start.c
index c97a10d..aff4fa4 100644
--- a/src/tss2-esys/api/Esys_HMAC_Start.c
+++ b/src/tss2-esys/api/Esys_HMAC_Start.c
@@ -158,6 +158,7 @@
     TSS2L_SYS_AUTH_COMMAND auths;
     RSRC_NODE_T *handleNode;
 
+    /* Check context, sequence correctness and set state to error for now */
     if (esysContext == NULL) {
         LOG_ERROR("esyscontext is NULL.");
         return TSS2_ESYS_RC_BAD_REFERENCE;
@@ -165,41 +166,44 @@
     r = iesys_check_sequence_async(esysContext);
     if (r != TSS2_RC_SUCCESS)
         return r;
-    r = check_session_feasability(shandle1, shandle2, shandle3, 1);
-    return_if_error(r, "Check session usage");
+    esysContext->state = _ESYS_STATE_INTERNALERROR;
 
+    /* Check and store input parameters */
+    r = check_session_feasability(shandle1, shandle2, shandle3, 1);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Check session usage");
     store_input_parameters(esysContext, handle,
                 auth,
                 hashAlg);
+
+    /* Retrieve the metadata objects for provided handles */
     r = esys_GetResourceObject(esysContext, handle, &handleNode);
-    if (r != TPM2_RC_SUCCESS)
-        return r;
+    return_state_if_error(r, _ESYS_STATE_INIT, "handle unknown.");
+
+    /* Initial invocation of SAPI to prepare the command buffer with parameters */
     r = Tss2_Sys_HMAC_Start_Prepare(esysContext->sys,
                 (handleNode == NULL) ? TPM2_RH_NULL : handleNode->rsrc.handle,
                 auth,
                 hashAlg);
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error async HMAC_Start");
-        return r;
-    }
-    r = init_session_tab(esysContext, shandle1, shandle2, shandle3);
-    return_if_error(r, "Initialize session resources");
+    return_state_if_error(r, _ESYS_STATE_INIT, "SAPI Prepare returned error.");
 
+    /* Calculate the cpHash Values */
+    r = init_session_tab(esysContext, shandle1, shandle2, shandle3);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Initialize session resources");
     iesys_compute_session_value(esysContext->session_tab[0],
                 &handleNode->rsrc.name, &handleNode->auth);
     iesys_compute_session_value(esysContext->session_tab[1], NULL, NULL);
     iesys_compute_session_value(esysContext->session_tab[2], NULL, NULL);
-    r = iesys_gen_auths(esysContext, handleNode, NULL, NULL, &auths);
-    return_if_error(r, "Error in computation of auth values");
 
+    /* Generate the auth values and set them in the SAPI command buffer */
+    r = iesys_gen_auths(esysContext, handleNode, NULL, NULL, &auths);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Error in computation of auth values");
     esysContext->authsCount = auths.count;
     r = Tss2_Sys_SetCmdAuths(esysContext->sys, &auths);
-    if (r != TSS2_RC_SUCCESS) {
-        return r;
-    }
+    return_state_if_error(r, _ESYS_STATE_INIT, "SAPI error on SetCmdAuths");
 
+    /* Trigger execution and finish the async invocation */
     r = Tss2_Sys_ExecuteAsync(esysContext->sys);
-    return_if_error(r, "Finish (Execute Async)");
+    return_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Finish (Execute Async)");
 
     esysContext->state = _ESYS_STATE_SENT;
 
@@ -225,18 +229,22 @@
     ESYS_TR *sequenceHandle)
 {
     LOG_TRACE("complete");
+    TSS2_RC r;
     if (esysContext == NULL) {
         LOG_ERROR("esyscontext is NULL.");
         return TSS2_ESYS_RC_BAD_REFERENCE;
     }
+
+    /* Check for correct sequence and set sequence to irregular for now */
     if (esysContext->state != _ESYS_STATE_SENT) {
         LOG_ERROR("Esys called in bad sequence.");
         return TSS2_ESYS_RC_BAD_SEQUENCE;
     }
-    TSS2_RC r;
-    IESYS_RESOURCE *sequenceHandleRsrc = NULL;
+    esysContext->state = _ESYS_STATE_INTERNALERROR;
     RSRC_NODE_T *sequenceHandleNode = NULL;
 
+
+    /* Allocate memory for response parameters */
     if (sequenceHandle == NULL) {
         LOG_ERROR("Handle sequenceHandle may not be NULL");
         return TSS2_ESYS_RC_BAD_REFERENCE;
@@ -246,17 +254,22 @@
     if (r != TSS2_RC_SUCCESS)
         return r;
 
+
+    /*Receive the TPM response and handle resubmissions if necessary. */
     r = Tss2_Sys_ExecuteFinish(esysContext->sys, esysContext->timeout);
     if ((r & ~TSS2_RC_LAYER_MASK) == TSS2_BASE_RC_TRY_AGAIN) {
         LOG_DEBUG("A layer below returned TRY_AGAIN: %" PRIx32, r);
+        esysContext->state = _ESYS_STATE_SENT;
         goto error_cleanup;
     }
+    /* This block handle the resubmission of TPM commands given a certain set of
+     * TPM response codes. */
     if (r == TPM2_RC_RETRY || r == TPM2_RC_TESTING || r == TPM2_RC_YIELDED) {
         LOG_DEBUG("TPM returned RETRY, TESTING or YIELDED, which triggers a "
             "resubmission: %" PRIx32, r);
         if (esysContext->submissionCount >= _ESYS_MAX_SUBMISSIONS) {
-            LOG_WARNING("Maximum number of resubmissions has been reached.");
-            esysContext->state = _ESYS_STATE_ERRORRESPONSE;
+            LOG_WARNING("Maximum number of (re)submissions has been reached.");
+            esysContext->state = _ESYS_STATE_INIT;
             goto error_cleanup;
         }
         esysContext->state = _ESYS_STATE_RESUBMISSION;
@@ -268,22 +281,32 @@
                 esysContext->in.HMAC_Start.auth,
                 esysContext->in.HMAC_Start.hashAlg);
         if (r != TSS2_RC_SUCCESS) {
-            LOG_ERROR("Error attempting to resubmit");
+            LOG_WARNING("Error attempting to resubmit");
+            /* We do not set esysContext->state here but inherit the most recent
+             * state of the _async function. */
             goto error_cleanup;
         }
         r = TSS2_ESYS_RC_TRY_AGAIN;
+        LOG_DEBUG("Resubmission initiated and returning RC_TRY_AGAIN.");
         goto error_cleanup;
     }
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error finish (ExecuteFinish) HMAC_Start");
+    /* The following is the "regular error" handling. */
+    if (r != TSS2_RC_SUCCESS && (r & TSS2_RC_LAYER_MASK) == 0) {
+        LOG_WARNING("Received TPM Error");
+        esysContext->state = _ESYS_STATE_INIT;
+        goto error_cleanup;
+    } else if (r != TSS2_RC_SUCCESS) {
+        LOG_ERROR("Received a non-TPM Error");
+        esysContext->state = _ESYS_STATE_INTERNALERROR;
         goto error_cleanup;
     }
+
     /*
      * Now the verification of the response (hmac check) and if necessary the
-     * parameter decryption have to be done
+     * parameter decryption have to be done.
      */
     r = iesys_check_response(esysContext);
-    goto_if_error(r, "Error: check response",
+    goto_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Error: check response",
                       error_cleanup);
     /*
      * After the verification of the response we call the complete function
@@ -291,20 +314,21 @@
      */
     r = Tss2_Sys_HMAC_Start_Complete(esysContext->sys,
                 &sequenceHandleNode->rsrc.handle);
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error finish (ExecuteFinish) HMAC_Start: %" PRIx32, r);
-        esysContext->state = _ESYS_STATE_ERRORRESPONSE;
-        goto error_cleanup;;
-    }
+    goto_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Received error from SAPI"
+                        " unmarshalling" ,error_cleanup);
 
-    size_t offset = 0;
+    /*  The name of a sequence object is an empty buffer */
     sequenceHandleNode->rsrc.name.size = 0;
+    /* Store the auth value parameter in the object meta data */
     sequenceHandleNode->auth = *esysContext->in.HMAC_Start.auth;
-    esysContext->state = _ESYS_STATE_FINISHED;
+    esysContext->state = _ESYS_STATE_INIT;
+    LOG_DEBUG("context=%p, sequenceHandle=%p",
+              esysContext, sequenceHandle);
 
-    return r;
+    return TSS2_RC_SUCCESS;
 
 error_cleanup:
     Esys_TR_Close(esysContext, sequenceHandle);
+
     return r;
 }
diff --git a/src/tss2-esys/api/Esys_Hash.c b/src/tss2-esys/api/Esys_Hash.c
index 7d4af60..7c277fd 100644
--- a/src/tss2-esys/api/Esys_Hash.c
+++ b/src/tss2-esys/api/Esys_Hash.c
@@ -160,6 +160,7 @@
     TSS2_RC r;
     TSS2L_SYS_AUTH_COMMAND auths;
 
+    /* Check context, sequence correctness and set state to error for now */
     if (esysContext == NULL) {
         LOG_ERROR("esyscontext is NULL.");
         return TSS2_ESYS_RC_BAD_REFERENCE;
@@ -167,38 +168,40 @@
     r = iesys_check_sequence_async(esysContext);
     if (r != TSS2_RC_SUCCESS)
         return r;
-    r = check_session_feasability(shandle1, shandle2, shandle3, 0);
-    return_if_error(r, "Check session usage");
+    esysContext->state = _ESYS_STATE_INTERNALERROR;
 
+    /* Check and store input parameters */
+    r = check_session_feasability(shandle1, shandle2, shandle3, 0);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Check session usage");
     store_input_parameters(esysContext,
                 data,
                 hashAlg,
                 hierarchy);
+
+    /* Initial invocation of SAPI to prepare the command buffer with parameters */
     r = Tss2_Sys_Hash_Prepare(esysContext->sys,
                 data,
                 hashAlg,
                 hierarchy);
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error async Hash");
-        return r;
-    }
-    r = init_session_tab(esysContext, shandle1, shandle2, shandle3);
-    return_if_error(r, "Initialize session resources");
+    return_state_if_error(r, _ESYS_STATE_INIT, "SAPI Prepare returned error.");
 
+    /* Calculate the cpHash Values */
+    r = init_session_tab(esysContext, shandle1, shandle2, shandle3);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Initialize session resources");
     iesys_compute_session_value(esysContext->session_tab[0], NULL, NULL);
     iesys_compute_session_value(esysContext->session_tab[1], NULL, NULL);
     iesys_compute_session_value(esysContext->session_tab[2], NULL, NULL);
-    r = iesys_gen_auths(esysContext, NULL, NULL, NULL, &auths);
-    return_if_error(r, "Error in computation of auth values");
 
+    /* Generate the auth values and set them in the SAPI command buffer */
+    r = iesys_gen_auths(esysContext, NULL, NULL, NULL, &auths);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Error in computation of auth values");
     esysContext->authsCount = auths.count;
     r = Tss2_Sys_SetCmdAuths(esysContext->sys, &auths);
-    if (r != TSS2_RC_SUCCESS) {
-        return r;
-    }
+    return_state_if_error(r, _ESYS_STATE_INIT, "SAPI error on SetCmdAuths");
 
+    /* Trigger execution and finish the async invocation */
     r = Tss2_Sys_ExecuteAsync(esysContext->sys);
-    return_if_error(r, "Finish (Execute Async)");
+    return_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Finish (Execute Async)");
 
     esysContext->state = _ESYS_STATE_SENT;
 
@@ -228,15 +231,20 @@
     TPMT_TK_HASHCHECK **validation)
 {
     LOG_TRACE("complete");
+    TSS2_RC r;
     if (esysContext == NULL) {
         LOG_ERROR("esyscontext is NULL.");
         return TSS2_ESYS_RC_BAD_REFERENCE;
     }
+
+    /* Check for correct sequence and set sequence to irregular for now */
     if (esysContext->state != _ESYS_STATE_SENT) {
         LOG_ERROR("Esys called in bad sequence.");
         return TSS2_ESYS_RC_BAD_SEQUENCE;
     }
-    TSS2_RC r;
+    esysContext->state = _ESYS_STATE_INTERNALERROR;
+
+    /* Allocate memory for response parameters */
     if (outHash != NULL) {
         *outHash = calloc(sizeof(TPM2B_DIGEST), 1);
         if (*outHash == NULL) {
@@ -249,17 +257,22 @@
             goto_error(r, TSS2_ESYS_RC_MEMORY, "Out of memory", error_cleanup);
         }
     }
+
+    /*Receive the TPM response and handle resubmissions if necessary. */
     r = Tss2_Sys_ExecuteFinish(esysContext->sys, esysContext->timeout);
     if ((r & ~TSS2_RC_LAYER_MASK) == TSS2_BASE_RC_TRY_AGAIN) {
         LOG_DEBUG("A layer below returned TRY_AGAIN: %" PRIx32, r);
+        esysContext->state = _ESYS_STATE_SENT;
         goto error_cleanup;
     }
+    /* This block handle the resubmission of TPM commands given a certain set of
+     * TPM response codes. */
     if (r == TPM2_RC_RETRY || r == TPM2_RC_TESTING || r == TPM2_RC_YIELDED) {
         LOG_DEBUG("TPM returned RETRY, TESTING or YIELDED, which triggers a "
             "resubmission: %" PRIx32, r);
         if (esysContext->submissionCount >= _ESYS_MAX_SUBMISSIONS) {
-            LOG_WARNING("Maximum number of resubmissions has been reached.");
-            esysContext->state = _ESYS_STATE_ERRORRESPONSE;
+            LOG_WARNING("Maximum number of (re)submissions has been reached.");
+            esysContext->state = _ESYS_STATE_INIT;
             goto error_cleanup;
         }
         esysContext->state = _ESYS_STATE_RESUBMISSION;
@@ -271,22 +284,32 @@
                 esysContext->in.Hash.hashAlg,
                 esysContext->in.Hash.hierarchy);
         if (r != TSS2_RC_SUCCESS) {
-            LOG_ERROR("Error attempting to resubmit");
+            LOG_WARNING("Error attempting to resubmit");
+            /* We do not set esysContext->state here but inherit the most recent
+             * state of the _async function. */
             goto error_cleanup;
         }
         r = TSS2_ESYS_RC_TRY_AGAIN;
+        LOG_DEBUG("Resubmission initiated and returning RC_TRY_AGAIN.");
         goto error_cleanup;
     }
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error finish (ExecuteFinish) Hash");
+    /* The following is the "regular error" handling. */
+    if (r != TSS2_RC_SUCCESS && (r & TSS2_RC_LAYER_MASK) == 0) {
+        LOG_WARNING("Received TPM Error");
+        esysContext->state = _ESYS_STATE_INIT;
+        goto error_cleanup;
+    } else if (r != TSS2_RC_SUCCESS) {
+        LOG_ERROR("Received a non-TPM Error");
+        esysContext->state = _ESYS_STATE_INTERNALERROR;
         goto error_cleanup;
     }
+
     /*
      * Now the verification of the response (hmac check) and if necessary the
-     * parameter decryption have to be done
+     * parameter decryption have to be done.
      */
     r = iesys_check_response(esysContext);
-    goto_if_error(r, "Error: check response",
+    goto_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Error: check response",
                       error_cleanup);
     /*
      * After the verification of the response we call the complete function
@@ -295,19 +318,19 @@
     r = Tss2_Sys_Hash_Complete(esysContext->sys,
                 (outHash != NULL) ? *outHash : NULL,
                 (validation != NULL) ? *validation : NULL);
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error finish (ExecuteFinish) Hash: %" PRIx32, r);
-        esysContext->state = _ESYS_STATE_ERRORRESPONSE;
-        goto error_cleanup;;
-    }
-    esysContext->state = _ESYS_STATE_FINISHED;
+    goto_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Received error from SAPI"
+                        " unmarshalling" ,error_cleanup);
+    esysContext->state = _ESYS_STATE_INIT;
+    LOG_DEBUG("context=%p, outHash=%p, validation=%p",
+              esysContext, outHash, validation);
 
-    return r;
+    return TSS2_RC_SUCCESS;
 
 error_cleanup:
     if (outHash != NULL)
         SAFE_FREE(*outHash);
     if (validation != NULL)
         SAFE_FREE(*validation);
+
     return r;
 }
diff --git a/src/tss2-esys/api/Esys_HashSequenceStart.c b/src/tss2-esys/api/Esys_HashSequenceStart.c
index f0cc246..0e1feef 100644
--- a/src/tss2-esys/api/Esys_HashSequenceStart.c
+++ b/src/tss2-esys/api/Esys_HashSequenceStart.c
@@ -148,6 +148,7 @@
     TSS2_RC r;
     TSS2L_SYS_AUTH_COMMAND auths;
 
+    /* Check context, sequence correctness and set state to error for now */
     if (esysContext == NULL) {
         LOG_ERROR("esyscontext is NULL.");
         return TSS2_ESYS_RC_BAD_REFERENCE;
@@ -155,35 +156,38 @@
     r = iesys_check_sequence_async(esysContext);
     if (r != TSS2_RC_SUCCESS)
         return r;
-    r = check_session_feasability(shandle1, shandle2, shandle3, 0);
-    return_if_error(r, "Check session usage");
+    esysContext->state = _ESYS_STATE_INTERNALERROR;
 
+    /* Check and store input parameters */
+    r = check_session_feasability(shandle1, shandle2, shandle3, 0);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Check session usage");
     store_input_parameters(esysContext,
                 auth,
                 hashAlg);
+
+    /* Initial invocation of SAPI to prepare the command buffer with parameters */
     r = Tss2_Sys_HashSequenceStart_Prepare(esysContext->sys,
                 auth,
                 hashAlg);
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error async HashSequenceStart");
-        return r;
-    }
-    r = init_session_tab(esysContext, shandle1, shandle2, shandle3);
-    return_if_error(r, "Initialize session resources");
+    return_state_if_error(r, _ESYS_STATE_INIT, "SAPI Prepare returned error.");
 
+    /* Calculate the cpHash Values */
+    r = init_session_tab(esysContext, shandle1, shandle2, shandle3);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Initialize session resources");
     iesys_compute_session_value(esysContext->session_tab[0], NULL, NULL);
     iesys_compute_session_value(esysContext->session_tab[1], NULL, NULL);
-    r = iesys_gen_auths(esysContext, NULL, NULL, NULL, &auths);
-    return_if_error(r, "Error in computation of auth values");
+    iesys_compute_session_value(esysContext->session_tab[2], NULL, NULL);
 
+    /* Generate the auth values and set them in the SAPI command buffer */
+    r = iesys_gen_auths(esysContext, NULL, NULL, NULL, &auths);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Error in computation of auth values");
     esysContext->authsCount = auths.count;
     r = Tss2_Sys_SetCmdAuths(esysContext->sys, &auths);
-    if (r != TSS2_RC_SUCCESS) {
-        return r;
-    }
+    return_state_if_error(r, _ESYS_STATE_INIT, "SAPI error on SetCmdAuths");
 
+    /* Trigger execution and finish the async invocation */
     r = Tss2_Sys_ExecuteAsync(esysContext->sys);
-    return_if_error(r, "Finish (Execute Async)");
+    return_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Finish (Execute Async)");
 
     esysContext->state = _ESYS_STATE_SENT;
 
@@ -209,18 +213,22 @@
     ESYS_TR *sequenceHandle)
 {
     LOG_TRACE("complete");
+    TSS2_RC r;
     if (esysContext == NULL) {
         LOG_ERROR("esyscontext is NULL.");
         return TSS2_ESYS_RC_BAD_REFERENCE;
     }
+
+    /* Check for correct sequence and set sequence to irregular for now */
     if (esysContext->state != _ESYS_STATE_SENT) {
         LOG_ERROR("Esys called in bad sequence.");
         return TSS2_ESYS_RC_BAD_SEQUENCE;
     }
-    TSS2_RC r;
-    IESYS_RESOURCE *sequenceHandleRsrc = NULL;
+    esysContext->state = _ESYS_STATE_INTERNALERROR;
     RSRC_NODE_T *sequenceHandleNode = NULL;
 
+
+    /* Allocate memory for response parameters */
     if (sequenceHandle == NULL) {
         LOG_ERROR("Handle sequenceHandle may not be NULL");
         return TSS2_ESYS_RC_BAD_REFERENCE;
@@ -230,17 +238,22 @@
     if (r != TSS2_RC_SUCCESS)
         return r;
 
+
+    /*Receive the TPM response and handle resubmissions if necessary. */
     r = Tss2_Sys_ExecuteFinish(esysContext->sys, esysContext->timeout);
     if ((r & ~TSS2_RC_LAYER_MASK) == TSS2_BASE_RC_TRY_AGAIN) {
         LOG_DEBUG("A layer below returned TRY_AGAIN: %" PRIx32, r);
+        esysContext->state = _ESYS_STATE_SENT;
         goto error_cleanup;
     }
+    /* This block handle the resubmission of TPM commands given a certain set of
+     * TPM response codes. */
     if (r == TPM2_RC_RETRY || r == TPM2_RC_TESTING || r == TPM2_RC_YIELDED) {
         LOG_DEBUG("TPM returned RETRY, TESTING or YIELDED, which triggers a "
             "resubmission: %" PRIx32, r);
         if (esysContext->submissionCount >= _ESYS_MAX_SUBMISSIONS) {
-            LOG_WARNING("Maximum number of resubmissions has been reached.");
-            esysContext->state = _ESYS_STATE_ERRORRESPONSE;
+            LOG_WARNING("Maximum number of (re)submissions has been reached.");
+            esysContext->state = _ESYS_STATE_INIT;
             goto error_cleanup;
         }
         esysContext->state = _ESYS_STATE_RESUBMISSION;
@@ -251,22 +264,32 @@
                 esysContext->in.HashSequenceStart.auth,
                 esysContext->in.HashSequenceStart.hashAlg);
         if (r != TSS2_RC_SUCCESS) {
-            LOG_ERROR("Error attempting to resubmit");
+            LOG_WARNING("Error attempting to resubmit");
+            /* We do not set esysContext->state here but inherit the most recent
+             * state of the _async function. */
             goto error_cleanup;
         }
         r = TSS2_ESYS_RC_TRY_AGAIN;
+        LOG_DEBUG("Resubmission initiated and returning RC_TRY_AGAIN.");
         goto error_cleanup;
     }
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error finish (ExecuteFinish) HashSequenceStart");
+    /* The following is the "regular error" handling. */
+    if (r != TSS2_RC_SUCCESS && (r & TSS2_RC_LAYER_MASK) == 0) {
+        LOG_WARNING("Received TPM Error");
+        esysContext->state = _ESYS_STATE_INIT;
+        goto error_cleanup;
+    } else if (r != TSS2_RC_SUCCESS) {
+        LOG_ERROR("Received a non-TPM Error");
+        esysContext->state = _ESYS_STATE_INTERNALERROR;
         goto error_cleanup;
     }
+
     /*
      * Now the verification of the response (hmac check) and if necessary the
-     * parameter decryption have to be done
+     * parameter decryption have to be done.
      */
     r = iesys_check_response(esysContext);
-    goto_if_error(r, "Error: check response",
+    goto_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Error: check response",
                       error_cleanup);
     /*
      * After the verification of the response we call the complete function
@@ -274,19 +297,18 @@
      */
     r = Tss2_Sys_HashSequenceStart_Complete(esysContext->sys,
                 &sequenceHandleNode->rsrc.handle);
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error finish (ExecuteFinish) HashSequenceStart: %" PRIx32, r);
-        esysContext->state = _ESYS_STATE_ERRORRESPONSE;
-        goto error_cleanup;;
-    }
+    goto_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Received error from SAPI"
+                        " unmarshalling" ,error_cleanup);
 
-    size_t offset = 0;
     sequenceHandleNode->rsrc.name.size = 0;
-    esysContext->state = _ESYS_STATE_FINISHED;
+    esysContext->state = _ESYS_STATE_INIT;
+    LOG_DEBUG("context=%p, sequenceHandle=%p",
+              esysContext, sequenceHandle);
 
-    return r;
+    return TSS2_RC_SUCCESS;
 
 error_cleanup:
     Esys_TR_Close(esysContext, sequenceHandle);
+
     return r;
 }
diff --git a/src/tss2-esys/api/Esys_HierarchyChangeAuth.c b/src/tss2-esys/api/Esys_HierarchyChangeAuth.c
index 4284cbf..73ef0a7 100644
--- a/src/tss2-esys/api/Esys_HierarchyChangeAuth.c
+++ b/src/tss2-esys/api/Esys_HierarchyChangeAuth.c
@@ -148,6 +148,7 @@
     TSS2L_SYS_AUTH_COMMAND auths;
     RSRC_NODE_T *authHandleNode;
 
+    /* Check context, sequence correctness and set state to error for now */
     if (esysContext == NULL) {
         LOG_ERROR("esyscontext is NULL.");
         return TSS2_ESYS_RC_BAD_REFERENCE;
@@ -155,38 +156,42 @@
     r = iesys_check_sequence_async(esysContext);
     if (r != TSS2_RC_SUCCESS)
         return r;
-    r = check_session_feasability(shandle1, shandle2, shandle3, 1);
-    return_if_error(r, "Check session usage");
+    esysContext->state = _ESYS_STATE_INTERNALERROR;
 
+    /* Check and store input parameters */
+    r = check_session_feasability(shandle1, shandle2, shandle3, 1);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Check session usage");
     store_input_parameters(esysContext, authHandle,
                 newAuth);
+
+    /* Retrieve the metadata objects for provided handles */
     r = esys_GetResourceObject(esysContext, authHandle, &authHandleNode);
-    if (r != TPM2_RC_SUCCESS)
-        return r;
+    return_state_if_error(r, _ESYS_STATE_INIT, "authHandle unknown.");
+
+    /* Initial invocation of SAPI to prepare the command buffer with parameters */
     r = Tss2_Sys_HierarchyChangeAuth_Prepare(esysContext->sys,
                 (authHandleNode == NULL) ? TPM2_RH_NULL : authHandleNode->rsrc.handle,
                 newAuth);
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error async HierarchyChangeAuth");
-        return r;
-    }
-    r = init_session_tab(esysContext, shandle1, shandle2, shandle3);
-    return_if_error(r, "Initialize session resources");
+    return_state_if_error(r, _ESYS_STATE_INIT, "SAPI Prepare returned error.");
 
+    /* Calculate the cpHash Values */
+    r = init_session_tab(esysContext, shandle1, shandle2, shandle3);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Initialize session resources");
     iesys_compute_session_value(esysContext->session_tab[0],
                 &authHandleNode->rsrc.name, &authHandleNode->auth);
     iesys_compute_session_value(esysContext->session_tab[1], NULL, NULL);
-    r = iesys_gen_auths(esysContext, authHandleNode, NULL, NULL, &auths);
-    return_if_error(r, "Error in computation of auth values");
+    iesys_compute_session_value(esysContext->session_tab[2], NULL, NULL);
 
+    /* Generate the auth values and set them in the SAPI command buffer */
+    r = iesys_gen_auths(esysContext, authHandleNode, NULL, NULL, &auths);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Error in computation of auth values");
     esysContext->authsCount = auths.count;
     r = Tss2_Sys_SetCmdAuths(esysContext->sys, &auths);
-    if (r != TSS2_RC_SUCCESS) {
-        return r;
-    }
+    return_state_if_error(r, _ESYS_STATE_INIT, "SAPI error on SetCmdAuths");
 
+    /* Trigger execution and finish the async invocation */
     r = Tss2_Sys_ExecuteAsync(esysContext->sys);
-    return_if_error(r, "Finish (Execute Async)");
+    return_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Finish (Execute Async)");
 
     esysContext->state = _ESYS_STATE_SENT;
 
@@ -213,26 +218,34 @@
     RSRC_NODE_T *authHandleNode;
 
     LOG_TRACE("complete");
+    TSS2_RC r;
     if (esysContext == NULL) {
         LOG_ERROR("esyscontext is NULL.");
         return TSS2_ESYS_RC_BAD_REFERENCE;
     }
+
+    /* Check for correct sequence and set sequence to irregular for now */
     if (esysContext->state != _ESYS_STATE_SENT) {
         LOG_ERROR("Esys called in bad sequence.");
         return TSS2_ESYS_RC_BAD_SEQUENCE;
     }
-    TSS2_RC r;
+    esysContext->state = _ESYS_STATE_INTERNALERROR;
+
+    /*Receive the TPM response and handle resubmissions if necessary. */
     r = Tss2_Sys_ExecuteFinish(esysContext->sys, esysContext->timeout);
     if ((r & ~TSS2_RC_LAYER_MASK) == TSS2_BASE_RC_TRY_AGAIN) {
         LOG_DEBUG("A layer below returned TRY_AGAIN: %" PRIx32, r);
+        esysContext->state = _ESYS_STATE_SENT;
         return r;
     }
+    /* This block handle the resubmission of TPM commands given a certain set of
+     * TPM response codes. */
     if (r == TPM2_RC_RETRY || r == TPM2_RC_TESTING || r == TPM2_RC_YIELDED) {
         LOG_DEBUG("TPM returned RETRY, TESTING or YIELDED, which triggers a "
             "resubmission: %" PRIx32, r);
         if (esysContext->submissionCount >= _ESYS_MAX_SUBMISSIONS) {
-            LOG_WARNING("Maximum number of resubmissions has been reached.");
-            esysContext->state = _ESYS_STATE_ERRORRESPONSE;
+            LOG_WARNING("Maximum number of (re)submissions has been reached.");
+            esysContext->state = _ESYS_STATE_INIT;
             return r;
         }
         esysContext->state = _ESYS_STATE_RESUBMISSION;
@@ -243,14 +256,23 @@
                 esysContext->session_type[2],
                 esysContext->in.HierarchyChangeAuth.newAuth);
         if (r != TSS2_RC_SUCCESS) {
-            LOG_ERROR("Error attempting to resubmit");
+            LOG_WARNING("Error attempting to resubmit");
+            /* We do not set esysContext->state here but inherit the most recent
+             * state of the _async function. */
             return r;
         }
         r = TSS2_ESYS_RC_TRY_AGAIN;
+        LOG_DEBUG("Resubmission initiated and returning RC_TRY_AGAIN.");
         return r;
     }
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error finish (ExecuteFinish) HierarchyChangeAuth");
+    /* The following is the "regular error" handling. */
+    if (r != TSS2_RC_SUCCESS && (r & TSS2_RC_LAYER_MASK) == 0) {
+        LOG_WARNING("Received TPM Error");
+        esysContext->state = _ESYS_STATE_INIT;
+        return r;
+    } else if (r != TSS2_RC_SUCCESS) {
+        LOG_ERROR("Received a non-TPM Error");
+        esysContext->state = _ESYS_STATE_INTERNALERROR;
         return r;
     }
     /*
@@ -267,21 +289,20 @@
 
     /*
      * Now the verification of the response (hmac check) and if necessary the
-     * parameter decryption have to be done
+     * parameter decryption have to be done.
      */
     r = iesys_check_response(esysContext);
-    return_if_error(r, "Error: check response");
+    return_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Error: check response");
     /*
      * After the verification of the response we call the complete function
      * to deliver the result.
      */
     r = Tss2_Sys_HierarchyChangeAuth_Complete(esysContext->sys);
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error finish (ExecuteFinish) HierarchyChangeAuth: %" PRIx32, r);
-        esysContext->state = _ESYS_STATE_ERRORRESPONSE;
-        return r;;
-    }
-    esysContext->state = _ESYS_STATE_FINISHED;
+    return_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Received error from SAPI"
+                        " unmarshalling" );
+    esysContext->state = _ESYS_STATE_INIT;
+    LOG_DEBUG("context=%p",
+              esysContext);
 
-    return r;
+    return TSS2_RC_SUCCESS;
 }
diff --git a/src/tss2-esys/api/Esys_HierarchyControl.c b/src/tss2-esys/api/Esys_HierarchyControl.c
index 2f69f3d..7c6c9ae 100644
--- a/src/tss2-esys/api/Esys_HierarchyControl.c
+++ b/src/tss2-esys/api/Esys_HierarchyControl.c
@@ -149,6 +149,7 @@
     TSS2L_SYS_AUTH_COMMAND auths;
     RSRC_NODE_T *authHandleNode;
 
+    /* Check context, sequence correctness and set state to error for now */
     if (esysContext == NULL) {
         LOG_ERROR("esyscontext is NULL.");
         return TSS2_ESYS_RC_BAD_REFERENCE;
@@ -156,41 +157,44 @@
     r = iesys_check_sequence_async(esysContext);
     if (r != TSS2_RC_SUCCESS)
         return r;
-    r = check_session_feasability(shandle1, shandle2, shandle3, 1);
-    return_if_error(r, "Check session usage");
+    esysContext->state = _ESYS_STATE_INTERNALERROR;
 
+    /* Check and store input parameters */
+    r = check_session_feasability(shandle1, shandle2, shandle3, 1);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Check session usage");
     store_input_parameters(esysContext, authHandle,
                 enable,
                 state);
+
+    /* Retrieve the metadata objects for provided handles */
     r = esys_GetResourceObject(esysContext, authHandle, &authHandleNode);
-    if (r != TPM2_RC_SUCCESS)
-        return r;
+    return_state_if_error(r, _ESYS_STATE_INIT, "authHandle unknown.");
+
+    /* Initial invocation of SAPI to prepare the command buffer with parameters */
     r = Tss2_Sys_HierarchyControl_Prepare(esysContext->sys,
                 (authHandleNode == NULL) ? TPM2_RH_NULL : authHandleNode->rsrc.handle,
                 enable,
                 state);
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error async HierarchyControl");
-        return r;
-    }
-    r = init_session_tab(esysContext, shandle1, shandle2, shandle3);
-    return_if_error(r, "Initialize session resources");
+    return_state_if_error(r, _ESYS_STATE_INIT, "SAPI Prepare returned error.");
 
+    /* Calculate the cpHash Values */
+    r = init_session_tab(esysContext, shandle1, shandle2, shandle3);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Initialize session resources");
     iesys_compute_session_value(esysContext->session_tab[0],
                 &authHandleNode->rsrc.name, &authHandleNode->auth);
     iesys_compute_session_value(esysContext->session_tab[1], NULL, NULL);
     iesys_compute_session_value(esysContext->session_tab[2], NULL, NULL);
-    r = iesys_gen_auths(esysContext, authHandleNode, NULL, NULL, &auths);
-    return_if_error(r, "Error in computation of auth values");
 
+    /* Generate the auth values and set them in the SAPI command buffer */
+    r = iesys_gen_auths(esysContext, authHandleNode, NULL, NULL, &auths);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Error in computation of auth values");
     esysContext->authsCount = auths.count;
     r = Tss2_Sys_SetCmdAuths(esysContext->sys, &auths);
-    if (r != TSS2_RC_SUCCESS) {
-        return r;
-    }
+    return_state_if_error(r, _ESYS_STATE_INIT, "SAPI error on SetCmdAuths");
 
+    /* Trigger execution and finish the async invocation */
     r = Tss2_Sys_ExecuteAsync(esysContext->sys);
-    return_if_error(r, "Finish (Execute Async)");
+    return_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Finish (Execute Async)");
 
     esysContext->state = _ESYS_STATE_SENT;
 
@@ -214,26 +218,34 @@
     ESYS_CONTEXT *esysContext)
 {
     LOG_TRACE("complete");
+    TSS2_RC r;
     if (esysContext == NULL) {
         LOG_ERROR("esyscontext is NULL.");
         return TSS2_ESYS_RC_BAD_REFERENCE;
     }
+
+    /* Check for correct sequence and set sequence to irregular for now */
     if (esysContext->state != _ESYS_STATE_SENT) {
         LOG_ERROR("Esys called in bad sequence.");
         return TSS2_ESYS_RC_BAD_SEQUENCE;
     }
-    TSS2_RC r;
+    esysContext->state = _ESYS_STATE_INTERNALERROR;
+
+    /*Receive the TPM response and handle resubmissions if necessary. */
     r = Tss2_Sys_ExecuteFinish(esysContext->sys, esysContext->timeout);
     if ((r & ~TSS2_RC_LAYER_MASK) == TSS2_BASE_RC_TRY_AGAIN) {
         LOG_DEBUG("A layer below returned TRY_AGAIN: %" PRIx32, r);
+        esysContext->state = _ESYS_STATE_SENT;
         return r;
     }
+    /* This block handle the resubmission of TPM commands given a certain set of
+     * TPM response codes. */
     if (r == TPM2_RC_RETRY || r == TPM2_RC_TESTING || r == TPM2_RC_YIELDED) {
         LOG_DEBUG("TPM returned RETRY, TESTING or YIELDED, which triggers a "
             "resubmission: %" PRIx32, r);
         if (esysContext->submissionCount >= _ESYS_MAX_SUBMISSIONS) {
-            LOG_WARNING("Maximum number of resubmissions has been reached.");
-            esysContext->state = _ESYS_STATE_ERRORRESPONSE;
+            LOG_WARNING("Maximum number of (re)submissions has been reached.");
+            esysContext->state = _ESYS_STATE_INIT;
             return r;
         }
         esysContext->state = _ESYS_STATE_RESUBMISSION;
@@ -245,33 +257,42 @@
                 esysContext->in.HierarchyControl.enable,
                 esysContext->in.HierarchyControl.state);
         if (r != TSS2_RC_SUCCESS) {
-            LOG_ERROR("Error attempting to resubmit");
+            LOG_WARNING("Error attempting to resubmit");
+            /* We do not set esysContext->state here but inherit the most recent
+             * state of the _async function. */
             return r;
         }
         r = TSS2_ESYS_RC_TRY_AGAIN;
+        LOG_DEBUG("Resubmission initiated and returning RC_TRY_AGAIN.");
         return r;
     }
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error finish (ExecuteFinish) HierarchyControl");
+    /* The following is the "regular error" handling. */
+    if (r != TSS2_RC_SUCCESS && (r & TSS2_RC_LAYER_MASK) == 0) {
+        LOG_WARNING("Received TPM Error");
+        esysContext->state = _ESYS_STATE_INIT;
+        return r;
+    } else if (r != TSS2_RC_SUCCESS) {
+        LOG_ERROR("Received a non-TPM Error");
+        esysContext->state = _ESYS_STATE_INTERNALERROR;
         return r;
     }
+
     /*
      * Now the verification of the response (hmac check) and if necessary the
-     * parameter decryption have to be done
+     * parameter decryption have to be done.
      */
     r = iesys_check_response(esysContext);
-    return_if_error(r, "Error: check response");
+    return_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Error: check response");
     /*
      * After the verification of the response we call the complete function
      * to deliver the result.
      */
     r = Tss2_Sys_HierarchyControl_Complete(esysContext->sys);
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error finish (ExecuteFinish) HierarchyControl: %" PRIx32, r);
-        esysContext->state = _ESYS_STATE_ERRORRESPONSE;
-        return r;;
-    }
-    esysContext->state = _ESYS_STATE_FINISHED;
+    return_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Received error from SAPI"
+                        " unmarshalling" );
+    esysContext->state = _ESYS_STATE_INIT;
+    LOG_DEBUG("context=%p",
+              esysContext);
 
-    return r;
+    return TSS2_RC_SUCCESS;
 }
diff --git a/src/tss2-esys/api/Esys_Import.c b/src/tss2-esys/api/Esys_Import.c
index 1224bb9..1015926 100644
--- a/src/tss2-esys/api/Esys_Import.c
+++ b/src/tss2-esys/api/Esys_Import.c
@@ -204,6 +204,7 @@
     TSS2L_SYS_AUTH_COMMAND auths;
     RSRC_NODE_T *parentHandleNode;
 
+    /* Check context, sequence correctness and set state to error for now */
     if (esysContext == NULL) {
         LOG_ERROR("esyscontext is NULL.");
         return TSS2_ESYS_RC_BAD_REFERENCE;
@@ -211,18 +212,23 @@
     r = iesys_check_sequence_async(esysContext);
     if (r != TSS2_RC_SUCCESS)
         return r;
-    r = check_session_feasability(shandle1, shandle2, shandle3, 1);
-    return_if_error(r, "Check session usage");
+    esysContext->state = _ESYS_STATE_INTERNALERROR;
 
+    /* Check and store input parameters */
+    r = check_session_feasability(shandle1, shandle2, shandle3, 1);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Check session usage");
     store_input_parameters(esysContext, parentHandle,
                 encryptionKey,
                 objectPublic,
                 duplicate,
                 inSymSeed,
                 symmetricAlg);
+
+    /* Retrieve the metadata objects for provided handles */
     r = esys_GetResourceObject(esysContext, parentHandle, &parentHandleNode);
-    if (r != TPM2_RC_SUCCESS)
-        return r;
+    return_state_if_error(r, _ESYS_STATE_INIT, "parentHandle unknown.");
+
+    /* Initial invocation of SAPI to prepare the command buffer with parameters */
     r = Tss2_Sys_Import_Prepare(esysContext->sys,
                 (parentHandleNode == NULL) ? TPM2_RH_NULL : parentHandleNode->rsrc.handle,
                 encryptionKey,
@@ -230,28 +236,26 @@
                 duplicate,
                 inSymSeed,
                 symmetricAlg);
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error async Import");
-        return r;
-    }
-    r = init_session_tab(esysContext, shandle1, shandle2, shandle3);
-    return_if_error(r, "Initialize session resources");
+    return_state_if_error(r, _ESYS_STATE_INIT, "SAPI Prepare returned error.");
 
+    /* Calculate the cpHash Values */
+    r = init_session_tab(esysContext, shandle1, shandle2, shandle3);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Initialize session resources");
     iesys_compute_session_value(esysContext->session_tab[0],
                 &parentHandleNode->rsrc.name, &parentHandleNode->auth);
     iesys_compute_session_value(esysContext->session_tab[1], NULL, NULL);
     iesys_compute_session_value(esysContext->session_tab[2], NULL, NULL);
-    r = iesys_gen_auths(esysContext, parentHandleNode, NULL, NULL, &auths);
-    return_if_error(r, "Error in computation of auth values");
 
+    /* Generate the auth values and set them in the SAPI command buffer */
+    r = iesys_gen_auths(esysContext, parentHandleNode, NULL, NULL, &auths);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Error in computation of auth values");
     esysContext->authsCount = auths.count;
     r = Tss2_Sys_SetCmdAuths(esysContext->sys, &auths);
-    if (r != TSS2_RC_SUCCESS) {
-        return r;
-    }
+    return_state_if_error(r, _ESYS_STATE_INIT, "SAPI error on SetCmdAuths");
 
+    /* Trigger execution and finish the async invocation */
     r = Tss2_Sys_ExecuteAsync(esysContext->sys);
-    return_if_error(r, "Finish (Execute Async)");
+    return_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Finish (Execute Async)");
 
     esysContext->state = _ESYS_STATE_SENT;
 
@@ -278,32 +282,42 @@
     TPM2B_PRIVATE **outPrivate)
 {
     LOG_TRACE("complete");
+    TSS2_RC r;
     if (esysContext == NULL) {
         LOG_ERROR("esyscontext is NULL.");
         return TSS2_ESYS_RC_BAD_REFERENCE;
     }
+
+    /* Check for correct sequence and set sequence to irregular for now */
     if (esysContext->state != _ESYS_STATE_SENT) {
         LOG_ERROR("Esys called in bad sequence.");
         return TSS2_ESYS_RC_BAD_SEQUENCE;
     }
-    TSS2_RC r;
+    esysContext->state = _ESYS_STATE_INTERNALERROR;
+
+    /* Allocate memory for response parameters */
     if (outPrivate != NULL) {
         *outPrivate = calloc(sizeof(TPM2B_PRIVATE), 1);
         if (*outPrivate == NULL) {
             return_error(TSS2_ESYS_RC_MEMORY, "Out of memory");
         }
     }
+
+    /*Receive the TPM response and handle resubmissions if necessary. */
     r = Tss2_Sys_ExecuteFinish(esysContext->sys, esysContext->timeout);
     if ((r & ~TSS2_RC_LAYER_MASK) == TSS2_BASE_RC_TRY_AGAIN) {
         LOG_DEBUG("A layer below returned TRY_AGAIN: %" PRIx32, r);
+        esysContext->state = _ESYS_STATE_SENT;
         goto error_cleanup;
     }
+    /* This block handle the resubmission of TPM commands given a certain set of
+     * TPM response codes. */
     if (r == TPM2_RC_RETRY || r == TPM2_RC_TESTING || r == TPM2_RC_YIELDED) {
         LOG_DEBUG("TPM returned RETRY, TESTING or YIELDED, which triggers a "
             "resubmission: %" PRIx32, r);
         if (esysContext->submissionCount >= _ESYS_MAX_SUBMISSIONS) {
-            LOG_WARNING("Maximum number of resubmissions has been reached.");
-            esysContext->state = _ESYS_STATE_ERRORRESPONSE;
+            LOG_WARNING("Maximum number of (re)submissions has been reached.");
+            esysContext->state = _ESYS_STATE_INIT;
             goto error_cleanup;
         }
         esysContext->state = _ESYS_STATE_RESUBMISSION;
@@ -318,22 +332,32 @@
                 esysContext->in.Import.inSymSeed,
                 esysContext->in.Import.symmetricAlg);
         if (r != TSS2_RC_SUCCESS) {
-            LOG_ERROR("Error attempting to resubmit");
+            LOG_WARNING("Error attempting to resubmit");
+            /* We do not set esysContext->state here but inherit the most recent
+             * state of the _async function. */
             goto error_cleanup;
         }
         r = TSS2_ESYS_RC_TRY_AGAIN;
+        LOG_DEBUG("Resubmission initiated and returning RC_TRY_AGAIN.");
         goto error_cleanup;
     }
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error finish (ExecuteFinish) Import");
+    /* The following is the "regular error" handling. */
+    if (r != TSS2_RC_SUCCESS && (r & TSS2_RC_LAYER_MASK) == 0) {
+        LOG_WARNING("Received TPM Error");
+        esysContext->state = _ESYS_STATE_INIT;
+        goto error_cleanup;
+    } else if (r != TSS2_RC_SUCCESS) {
+        LOG_ERROR("Received a non-TPM Error");
+        esysContext->state = _ESYS_STATE_INTERNALERROR;
         goto error_cleanup;
     }
+
     /*
      * Now the verification of the response (hmac check) and if necessary the
-     * parameter decryption have to be done
+     * parameter decryption have to be done.
      */
     r = iesys_check_response(esysContext);
-    goto_if_error(r, "Error: check response",
+    goto_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Error: check response",
                       error_cleanup);
     /*
      * After the verification of the response we call the complete function
@@ -341,17 +365,17 @@
      */
     r = Tss2_Sys_Import_Complete(esysContext->sys,
                 (outPrivate != NULL) ? *outPrivate : NULL);
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error finish (ExecuteFinish) Import: %" PRIx32, r);
-        esysContext->state = _ESYS_STATE_ERRORRESPONSE;
-        goto error_cleanup;;
-    }
-    esysContext->state = _ESYS_STATE_FINISHED;
+    goto_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Received error from SAPI"
+                        " unmarshalling" ,error_cleanup);
+    esysContext->state = _ESYS_STATE_INIT;
+    LOG_DEBUG("context=%p, outPrivate=%p",
+              esysContext, outPrivate);
 
-    return r;
+    return TSS2_RC_SUCCESS;
 
 error_cleanup:
     if (outPrivate != NULL)
         SAFE_FREE(*outPrivate);
+
     return r;
 }
diff --git a/src/tss2-esys/api/Esys_IncrementalSelfTest.c b/src/tss2-esys/api/Esys_IncrementalSelfTest.c
index e756942..428b694 100644
--- a/src/tss2-esys/api/Esys_IncrementalSelfTest.c
+++ b/src/tss2-esys/api/Esys_IncrementalSelfTest.c
@@ -142,6 +142,7 @@
     TSS2_RC r;
     TSS2L_SYS_AUTH_COMMAND auths;
 
+    /* Check context, sequence correctness and set state to error for now */
     if (esysContext == NULL) {
         LOG_ERROR("esyscontext is NULL.");
         return TSS2_ESYS_RC_BAD_REFERENCE;
@@ -149,32 +150,36 @@
     r = iesys_check_sequence_async(esysContext);
     if (r != TSS2_RC_SUCCESS)
         return r;
-    r = check_session_feasability(shandle1, shandle2, shandle3, 0);
-    return_if_error(r, "Check session usage");
+    esysContext->state = _ESYS_STATE_INTERNALERROR;
 
+    /* Check and store input parameters */
+    r = check_session_feasability(shandle1, shandle2, shandle3, 0);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Check session usage");
     store_input_parameters(esysContext,
                 toTest);
+
+    /* Initial invocation of SAPI to prepare the command buffer with parameters */
     r = Tss2_Sys_IncrementalSelfTest_Prepare(esysContext->sys,
                 toTest);
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error async IncrementalSelfTest");
-        return r;
-    }
+    return_state_if_error(r, _ESYS_STATE_INIT, "SAPI Prepare returned error.");
+
+    /* Calculate the cpHash Values */
     r = init_session_tab(esysContext, shandle1, shandle2, shandle3);
-    return_if_error(r, "Initialize session resources");
-
+    return_state_if_error(r, _ESYS_STATE_INIT, "Initialize session resources");
     iesys_compute_session_value(esysContext->session_tab[0], NULL, NULL);
-    r = iesys_gen_auths(esysContext, NULL, NULL, NULL, &auths);
-    return_if_error(r, "Error in computation of auth values");
+    iesys_compute_session_value(esysContext->session_tab[1], NULL, NULL);
+    iesys_compute_session_value(esysContext->session_tab[2], NULL, NULL);
 
+    /* Generate the auth values and set them in the SAPI command buffer */
+    r = iesys_gen_auths(esysContext, NULL, NULL, NULL, &auths);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Error in computation of auth values");
     esysContext->authsCount = auths.count;
     r = Tss2_Sys_SetCmdAuths(esysContext->sys, &auths);
-    if (r != TSS2_RC_SUCCESS) {
-        return r;
-    }
+    return_state_if_error(r, _ESYS_STATE_INIT, "SAPI error on SetCmdAuths");
 
+    /* Trigger execution and finish the async invocation */
     r = Tss2_Sys_ExecuteAsync(esysContext->sys);
-    return_if_error(r, "Finish (Execute Async)");
+    return_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Finish (Execute Async)");
 
     esysContext->state = _ESYS_STATE_SENT;
 
@@ -201,32 +206,42 @@
     TPML_ALG **toDoList)
 {
     LOG_TRACE("complete");
+    TSS2_RC r;
     if (esysContext == NULL) {
         LOG_ERROR("esyscontext is NULL.");
         return TSS2_ESYS_RC_BAD_REFERENCE;
     }
+
+    /* Check for correct sequence and set sequence to irregular for now */
     if (esysContext->state != _ESYS_STATE_SENT) {
         LOG_ERROR("Esys called in bad sequence.");
         return TSS2_ESYS_RC_BAD_SEQUENCE;
     }
-    TSS2_RC r;
+    esysContext->state = _ESYS_STATE_INTERNALERROR;
+
+    /* Allocate memory for response parameters */
     if (toDoList != NULL) {
         *toDoList = calloc(sizeof(TPML_ALG), 1);
         if (*toDoList == NULL) {
             return_error(TSS2_ESYS_RC_MEMORY, "Out of memory");
         }
     }
+
+    /*Receive the TPM response and handle resubmissions if necessary. */
     r = Tss2_Sys_ExecuteFinish(esysContext->sys, esysContext->timeout);
     if ((r & ~TSS2_RC_LAYER_MASK) == TSS2_BASE_RC_TRY_AGAIN) {
         LOG_DEBUG("A layer below returned TRY_AGAIN: %" PRIx32, r);
+        esysContext->state = _ESYS_STATE_SENT;
         goto error_cleanup;
     }
+    /* This block handle the resubmission of TPM commands given a certain set of
+     * TPM response codes. */
     if (r == TPM2_RC_RETRY || r == TPM2_RC_TESTING || r == TPM2_RC_YIELDED) {
         LOG_DEBUG("TPM returned RETRY, TESTING or YIELDED, which triggers a "
             "resubmission: %" PRIx32, r);
         if (esysContext->submissionCount >= _ESYS_MAX_SUBMISSIONS) {
-            LOG_WARNING("Maximum number of resubmissions has been reached.");
-            esysContext->state = _ESYS_STATE_ERRORRESPONSE;
+            LOG_WARNING("Maximum number of (re)submissions has been reached.");
+            esysContext->state = _ESYS_STATE_INIT;
             goto error_cleanup;
         }
         esysContext->state = _ESYS_STATE_RESUBMISSION;
@@ -236,22 +251,32 @@
                 esysContext->session_type[2],
                 esysContext->in.IncrementalSelfTest.toTest);
         if (r != TSS2_RC_SUCCESS) {
-            LOG_ERROR("Error attempting to resubmit");
+            LOG_WARNING("Error attempting to resubmit");
+            /* We do not set esysContext->state here but inherit the most recent
+             * state of the _async function. */
             goto error_cleanup;
         }
         r = TSS2_ESYS_RC_TRY_AGAIN;
+        LOG_DEBUG("Resubmission initiated and returning RC_TRY_AGAIN.");
         goto error_cleanup;
     }
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error finish (ExecuteFinish) IncrementalSelfTest");
+    /* The following is the "regular error" handling. */
+    if (r != TSS2_RC_SUCCESS && (r & TSS2_RC_LAYER_MASK) == 0) {
+        LOG_WARNING("Received TPM Error");
+        esysContext->state = _ESYS_STATE_INIT;
+        goto error_cleanup;
+    } else if (r != TSS2_RC_SUCCESS) {
+        LOG_ERROR("Received a non-TPM Error");
+        esysContext->state = _ESYS_STATE_INTERNALERROR;
         goto error_cleanup;
     }
+
     /*
      * Now the verification of the response (hmac check) and if necessary the
-     * parameter decryption have to be done
+     * parameter decryption have to be done.
      */
     r = iesys_check_response(esysContext);
-    goto_if_error(r, "Error: check response",
+    goto_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Error: check response",
                       error_cleanup);
     /*
      * After the verification of the response we call the complete function
@@ -259,17 +284,17 @@
      */
     r = Tss2_Sys_IncrementalSelfTest_Complete(esysContext->sys,
                 (toDoList != NULL) ? *toDoList : NULL);
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error finish (ExecuteFinish) IncrementalSelfTest: %" PRIx32, r);
-        esysContext->state = _ESYS_STATE_ERRORRESPONSE;
-        goto error_cleanup;;
-    }
-    esysContext->state = _ESYS_STATE_FINISHED;
+    goto_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Received error from SAPI"
+                        " unmarshalling" ,error_cleanup);
+    esysContext->state = _ESYS_STATE_INIT;
+    LOG_DEBUG("context=%p, toDoList=%p",
+              esysContext, toDoList);
 
-    return r;
+    return TSS2_RC_SUCCESS;
 
 error_cleanup:
     if (toDoList != NULL)
         SAFE_FREE(*toDoList);
+
     return r;
 }
diff --git a/src/tss2-esys/api/Esys_Load.c b/src/tss2-esys/api/Esys_Load.c
index c421b33..b6b473b 100644
--- a/src/tss2-esys/api/Esys_Load.c
+++ b/src/tss2-esys/api/Esys_Load.c
@@ -164,6 +164,7 @@
     TSS2L_SYS_AUTH_COMMAND auths;
     RSRC_NODE_T *parentHandleNode;
 
+    /* Check context, sequence correctness and set state to error for now */
     if (esysContext == NULL) {
         LOG_ERROR("esyscontext is NULL.");
         return TSS2_ESYS_RC_BAD_REFERENCE;
@@ -171,41 +172,44 @@
     r = iesys_check_sequence_async(esysContext);
     if (r != TSS2_RC_SUCCESS)
         return r;
-    r = check_session_feasability(shandle1, shandle2, shandle3, 1);
-    return_if_error(r, "Check session usage");
+    esysContext->state = _ESYS_STATE_INTERNALERROR;
 
+    /* Check and store input parameters */
+    r = check_session_feasability(shandle1, shandle2, shandle3, 1);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Check session usage");
     store_input_parameters(esysContext, parentHandle,
                 inPrivate,
                 inPublic);
+
+    /* Retrieve the metadata objects for provided handles */
     r = esys_GetResourceObject(esysContext, parentHandle, &parentHandleNode);
-    if (r != TPM2_RC_SUCCESS)
-        return r;
+    return_state_if_error(r, _ESYS_STATE_INIT, "parentHandle unknown.");
+
+    /* Initial invocation of SAPI to prepare the command buffer with parameters */
     r = Tss2_Sys_Load_Prepare(esysContext->sys,
                 (parentHandleNode == NULL) ? TPM2_RH_NULL : parentHandleNode->rsrc.handle,
                 inPrivate,
                 inPublic);
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error async Load");
-        return r;
-    }
-    r = init_session_tab(esysContext, shandle1, shandle2, shandle3);
-    return_if_error(r, "Initialize session resources");
+    return_state_if_error(r, _ESYS_STATE_INIT, "SAPI Prepare returned error.");
 
+    /* Calculate the cpHash Values */
+    r = init_session_tab(esysContext, shandle1, shandle2, shandle3);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Initialize session resources");
     iesys_compute_session_value(esysContext->session_tab[0],
                 &parentHandleNode->rsrc.name, &parentHandleNode->auth);
     iesys_compute_session_value(esysContext->session_tab[1], NULL, NULL);
     iesys_compute_session_value(esysContext->session_tab[2], NULL, NULL);
-    r = iesys_gen_auths(esysContext, parentHandleNode, NULL, NULL, &auths);
-    return_if_error(r, "Error in computation of auth values");
 
+    /* Generate the auth values and set them in the SAPI command buffer */
+    r = iesys_gen_auths(esysContext, parentHandleNode, NULL, NULL, &auths);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Error in computation of auth values");
     esysContext->authsCount = auths.count;
     r = Tss2_Sys_SetCmdAuths(esysContext->sys, &auths);
-    if (r != TSS2_RC_SUCCESS) {
-        return r;
-    }
+    return_state_if_error(r, _ESYS_STATE_INIT, "SAPI error on SetCmdAuths");
 
+    /* Trigger execution and finish the async invocation */
     r = Tss2_Sys_ExecuteAsync(esysContext->sys);
-    return_if_error(r, "Finish (Execute Async)");
+    return_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Finish (Execute Async)");
 
     esysContext->state = _ESYS_STATE_SENT;
 
@@ -231,19 +235,23 @@
     ESYS_TR *objectHandle)
 {
     LOG_TRACE("complete");
+    TSS2_RC r;
     if (esysContext == NULL) {
         LOG_ERROR("esyscontext is NULL.");
         return TSS2_ESYS_RC_BAD_REFERENCE;
     }
+
+    /* Check for correct sequence and set sequence to irregular for now */
     if (esysContext->state != _ESYS_STATE_SENT) {
         LOG_ERROR("Esys called in bad sequence.");
         return TSS2_ESYS_RC_BAD_SEQUENCE;
     }
-    TSS2_RC r;
+    esysContext->state = _ESYS_STATE_INTERNALERROR;
     TPM2B_NAME name;
-    IESYS_RESOURCE *objectHandleRsrc = NULL;
     RSRC_NODE_T *objectHandleNode = NULL;
 
+
+    /* Allocate memory for response parameters */
     if (objectHandle == NULL) {
         LOG_ERROR("Handle objectHandle may not be NULL");
         return TSS2_ESYS_RC_BAD_REFERENCE;
@@ -253,19 +261,26 @@
     if (r != TSS2_RC_SUCCESS)
         return r;
 
-    objectHandleNode->rsrc.rsrcType = IESYSC_KEY_RSRC;
-    objectHandleNode->rsrc.misc.rsrc_key_pub = *esysContext->in.Load.inPublic;
+
+     /* Update the meta data of the ESYS_TR object */
+     objectHandleNode->rsrc.rsrcType = IESYSC_KEY_RSRC;
+     objectHandleNode->rsrc.misc.rsrc_key_pub = *esysContext->in.Load.inPublic;
+
+    /*Receive the TPM response and handle resubmissions if necessary. */
     r = Tss2_Sys_ExecuteFinish(esysContext->sys, esysContext->timeout);
     if ((r & ~TSS2_RC_LAYER_MASK) == TSS2_BASE_RC_TRY_AGAIN) {
         LOG_DEBUG("A layer below returned TRY_AGAIN: %" PRIx32, r);
+        esysContext->state = _ESYS_STATE_SENT;
         goto error_cleanup;
     }
+    /* This block handle the resubmission of TPM commands given a certain set of
+     * TPM response codes. */
     if (r == TPM2_RC_RETRY || r == TPM2_RC_TESTING || r == TPM2_RC_YIELDED) {
         LOG_DEBUG("TPM returned RETRY, TESTING or YIELDED, which triggers a "
             "resubmission: %" PRIx32, r);
         if (esysContext->submissionCount >= _ESYS_MAX_SUBMISSIONS) {
-            LOG_WARNING("Maximum number of resubmissions has been reached.");
-            esysContext->state = _ESYS_STATE_ERRORRESPONSE;
+            LOG_WARNING("Maximum number of (re)submissions has been reached.");
+            esysContext->state = _ESYS_STATE_INIT;
             goto error_cleanup;
         }
         esysContext->state = _ESYS_STATE_RESUBMISSION;
@@ -277,22 +292,32 @@
                 esysContext->in.Load.inPrivate,
                 esysContext->in.Load.inPublic);
         if (r != TSS2_RC_SUCCESS) {
-            LOG_ERROR("Error attempting to resubmit");
+            LOG_WARNING("Error attempting to resubmit");
+            /* We do not set esysContext->state here but inherit the most recent
+             * state of the _async function. */
             goto error_cleanup;
         }
         r = TSS2_ESYS_RC_TRY_AGAIN;
+        LOG_DEBUG("Resubmission initiated and returning RC_TRY_AGAIN.");
         goto error_cleanup;
     }
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error finish (ExecuteFinish) Load");
+    /* The following is the "regular error" handling. */
+    if (r != TSS2_RC_SUCCESS && (r & TSS2_RC_LAYER_MASK) == 0) {
+        LOG_WARNING("Received TPM Error");
+        esysContext->state = _ESYS_STATE_INIT;
+        goto error_cleanup;
+    } else if (r != TSS2_RC_SUCCESS) {
+        LOG_ERROR("Received a non-TPM Error");
+        esysContext->state = _ESYS_STATE_INTERNALERROR;
         goto error_cleanup;
     }
+
     /*
      * Now the verification of the response (hmac check) and if necessary the
-     * parameter decryption have to be done
+     * parameter decryption have to be done.
      */
     r = iesys_check_response(esysContext);
-    goto_if_error(r, "Error: check response",
+    goto_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Error: check response",
                       error_cleanup);
     /*
      * After the verification of the response we call the complete function
@@ -301,21 +326,23 @@
     r = Tss2_Sys_Load_Complete(esysContext->sys,
                 &objectHandleNode->rsrc.handle,
                 &name);
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error finish (ExecuteFinish) Load: %" PRIx32, r);
-        esysContext->state = _ESYS_STATE_ERRORRESPONSE;
-        goto error_cleanup;;
-    }
-    if (!iesys_compare_name(esysContext->in.Load.inPublic, &name)) {
-        goto_error(r, TSS2_ESYS_RC_MALFORMED_RESPONSE,
-            "in Public name not equal name in response", error_cleanup);
+    goto_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Received error from SAPI"
+                        " unmarshalling" ,error_cleanup);
+
+     /* Check name and inPublic for consistency */
+     if (!iesys_compare_name(esysContext->in.Load.inPublic, &name)) {
+         goto_error(r, TSS2_ESYS_RC_MALFORMED_RESPONSE,
+                    "in Public name not equal name in response", error_cleanup);
     }
     objectHandleNode->rsrc.name = name;
-    esysContext->state = _ESYS_STATE_FINISHED;
+    esysContext->state = _ESYS_STATE_INIT;
+    LOG_DEBUG("context=%p, objectHandle=%p",
+              esysContext, objectHandle);
 
-    return r;
+    return TSS2_RC_SUCCESS;
 
 error_cleanup:
     Esys_TR_Close(esysContext, objectHandle);
+
     return r;
 }
diff --git a/src/tss2-esys/api/Esys_LoadExternal.c b/src/tss2-esys/api/Esys_LoadExternal.c
index 3e5a93f..3a71ee0 100644
--- a/src/tss2-esys/api/Esys_LoadExternal.c
+++ b/src/tss2-esys/api/Esys_LoadExternal.c
@@ -161,6 +161,7 @@
     TSS2_RC r;
     TSS2L_SYS_AUTH_COMMAND auths;
 
+    /* Check context, sequence correctness and set state to error for now */
     if (esysContext == NULL) {
         LOG_ERROR("esyscontext is NULL.");
         return TSS2_ESYS_RC_BAD_REFERENCE;
@@ -168,38 +169,40 @@
     r = iesys_check_sequence_async(esysContext);
     if (r != TSS2_RC_SUCCESS)
         return r;
-    r = check_session_feasability(shandle1, shandle2, shandle3, 0);
-    return_if_error(r, "Check session usage");
+    esysContext->state = _ESYS_STATE_INTERNALERROR;
 
+    /* Check and store input parameters */
+    r = check_session_feasability(shandle1, shandle2, shandle3, 0);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Check session usage");
     store_input_parameters(esysContext,
                 inPrivate,
                 inPublic,
                 hierarchy);
+
+    /* Initial invocation of SAPI to prepare the command buffer with parameters */
     r = Tss2_Sys_LoadExternal_Prepare(esysContext->sys,
                 inPrivate,
                 inPublic,
                 hierarchy);
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error async LoadExternal");
-        return r;
-    }
-    r = init_session_tab(esysContext, shandle1, shandle2, shandle3);
-    return_if_error(r, "Initialize session resources");
+    return_state_if_error(r, _ESYS_STATE_INIT, "SAPI Prepare returned error.");
 
+    /* Calculate the cpHash Values */
+    r = init_session_tab(esysContext, shandle1, shandle2, shandle3);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Initialize session resources");
     iesys_compute_session_value(esysContext->session_tab[0], NULL, NULL);
     iesys_compute_session_value(esysContext->session_tab[1], NULL, NULL);
     iesys_compute_session_value(esysContext->session_tab[2], NULL, NULL);
-    r = iesys_gen_auths(esysContext, NULL, NULL, NULL, &auths);
-    return_if_error(r, "Error in computation of auth values");
 
+    /* Generate the auth values and set them in the SAPI command buffer */
+    r = iesys_gen_auths(esysContext, NULL, NULL, NULL, &auths);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Error in computation of auth values");
     esysContext->authsCount = auths.count;
     r = Tss2_Sys_SetCmdAuths(esysContext->sys, &auths);
-    if (r != TSS2_RC_SUCCESS) {
-        return r;
-    }
+    return_state_if_error(r, _ESYS_STATE_INIT, "SAPI error on SetCmdAuths");
 
+    /* Trigger execution and finish the async invocation */
     r = Tss2_Sys_ExecuteAsync(esysContext->sys);
-    return_if_error(r, "Finish (Execute Async)");
+    return_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Finish (Execute Async)");
 
     esysContext->state = _ESYS_STATE_SENT;
 
@@ -225,19 +228,23 @@
     ESYS_TR *objectHandle)
 {
     LOG_TRACE("complete");
+    TSS2_RC r;
     if (esysContext == NULL) {
         LOG_ERROR("esyscontext is NULL.");
         return TSS2_ESYS_RC_BAD_REFERENCE;
     }
+
+    /* Check for correct sequence and set sequence to irregular for now */
     if (esysContext->state != _ESYS_STATE_SENT) {
         LOG_ERROR("Esys called in bad sequence.");
         return TSS2_ESYS_RC_BAD_SEQUENCE;
     }
-    TSS2_RC r;
+    esysContext->state = _ESYS_STATE_INTERNALERROR;
     TPM2B_NAME name;
-    IESYS_RESOURCE *objectHandleRsrc = NULL;
     RSRC_NODE_T *objectHandleNode = NULL;
 
+
+    /* Allocate memory for response parameters */
     if (objectHandle == NULL) {
         LOG_ERROR("Handle objectHandle may not be NULL");
         return TSS2_ESYS_RC_BAD_REFERENCE;
@@ -249,17 +256,22 @@
 
     objectHandleNode->rsrc.rsrcType = IESYSC_KEY_RSRC;
     objectHandleNode->rsrc.misc.rsrc_key_pub = *esysContext->in.LoadExternal.inPublic;
+
+    /*Receive the TPM response and handle resubmissions if necessary. */
     r = Tss2_Sys_ExecuteFinish(esysContext->sys, esysContext->timeout);
     if ((r & ~TSS2_RC_LAYER_MASK) == TSS2_BASE_RC_TRY_AGAIN) {
         LOG_DEBUG("A layer below returned TRY_AGAIN: %" PRIx32, r);
+        esysContext->state = _ESYS_STATE_SENT;
         goto error_cleanup;
     }
+    /* This block handle the resubmission of TPM commands given a certain set of
+     * TPM response codes. */
     if (r == TPM2_RC_RETRY || r == TPM2_RC_TESTING || r == TPM2_RC_YIELDED) {
         LOG_DEBUG("TPM returned RETRY, TESTING or YIELDED, which triggers a "
             "resubmission: %" PRIx32, r);
         if (esysContext->submissionCount >= _ESYS_MAX_SUBMISSIONS) {
-            LOG_WARNING("Maximum number of resubmissions has been reached.");
-            esysContext->state = _ESYS_STATE_ERRORRESPONSE;
+            LOG_WARNING("Maximum number of (re)submissions has been reached.");
+            esysContext->state = _ESYS_STATE_INIT;
             goto error_cleanup;
         }
         esysContext->state = _ESYS_STATE_RESUBMISSION;
@@ -271,22 +283,32 @@
                 esysContext->in.LoadExternal.inPublic,
                 esysContext->in.LoadExternal.hierarchy);
         if (r != TSS2_RC_SUCCESS) {
-            LOG_ERROR("Error attempting to resubmit");
+            LOG_WARNING("Error attempting to resubmit");
+            /* We do not set esysContext->state here but inherit the most recent
+             * state of the _async function. */
             goto error_cleanup;
         }
         r = TSS2_ESYS_RC_TRY_AGAIN;
+        LOG_DEBUG("Resubmission initiated and returning RC_TRY_AGAIN.");
         goto error_cleanup;
     }
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error finish (ExecuteFinish) LoadExternal");
+    /* The following is the "regular error" handling. */
+    if (r != TSS2_RC_SUCCESS && (r & TSS2_RC_LAYER_MASK) == 0) {
+        LOG_WARNING("Received TPM Error");
+        esysContext->state = _ESYS_STATE_INIT;
+        goto error_cleanup;
+    } else if (r != TSS2_RC_SUCCESS) {
+        LOG_ERROR("Received a non-TPM Error");
+        esysContext->state = _ESYS_STATE_INTERNALERROR;
         goto error_cleanup;
     }
+
     /*
      * Now the verification of the response (hmac check) and if necessary the
-     * parameter decryption have to be done
+     * parameter decryption have to be done.
      */
     r = iesys_check_response(esysContext);
-    goto_if_error(r, "Error: check response",
+    goto_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Error: check response",
                       error_cleanup);
     /*
      * After the verification of the response we call the complete function
@@ -295,22 +317,23 @@
     r = Tss2_Sys_LoadExternal_Complete(esysContext->sys,
                 &objectHandleNode->rsrc.handle,
                 &name);
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error finish (ExecuteFinish) LoadExternal: %" PRIx32, r);
-        esysContext->state = _ESYS_STATE_ERRORRESPONSE;
-        goto error_cleanup;;
-    }
+    goto_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Received error from SAPI"
+                        " unmarshalling" ,error_cleanup);
 
-    if (!iesys_compare_name(esysContext->in.LoadExternal.inPublic, &name)) {
-        goto_error(r, TSS2_ESYS_RC_MALFORMED_RESPONSE,
-                      "in Public name not equal name in response", error_cleanup);
+     /* check name against inPublic */
+     if (!iesys_compare_name(esysContext->in.LoadExternal.inPublic, &name)) {
+         goto_error(r, TSS2_ESYS_RC_MALFORMED_RESPONSE,
+                       "in Public name not equal name in response", error_cleanup);
     }
     objectHandleNode->rsrc.name = name;
-    esysContext->state = _ESYS_STATE_FINISHED;
+    esysContext->state = _ESYS_STATE_INIT;
+    LOG_DEBUG("context=%p, objectHandle=%p",
+              esysContext, objectHandle);
 
-    return r;
+    return TSS2_RC_SUCCESS;
 
 error_cleanup:
     Esys_TR_Close(esysContext, objectHandle);
+
     return r;
 }
diff --git a/src/tss2-esys/api/Esys_MakeCredential.c b/src/tss2-esys/api/Esys_MakeCredential.c
index e28a3be..c2cdaf2 100644
--- a/src/tss2-esys/api/Esys_MakeCredential.c
+++ b/src/tss2-esys/api/Esys_MakeCredential.c
@@ -169,6 +169,7 @@
     TSS2L_SYS_AUTH_COMMAND auths;
     RSRC_NODE_T *handleNode;
 
+    /* Check context, sequence correctness and set state to error for now */
     if (esysContext == NULL) {
         LOG_ERROR("esyscontext is NULL.");
         return TSS2_ESYS_RC_BAD_REFERENCE;
@@ -176,40 +177,43 @@
     r = iesys_check_sequence_async(esysContext);
     if (r != TSS2_RC_SUCCESS)
         return r;
-    r = check_session_feasability(shandle1, shandle2, shandle3, 0);
-    return_if_error(r, "Check session usage");
+    esysContext->state = _ESYS_STATE_INTERNALERROR;
 
+    /* Check and store input parameters */
+    r = check_session_feasability(shandle1, shandle2, shandle3, 0);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Check session usage");
     store_input_parameters(esysContext, handle,
                 credential,
                 objectName);
+
+    /* Retrieve the metadata objects for provided handles */
     r = esys_GetResourceObject(esysContext, handle, &handleNode);
-    if (r != TPM2_RC_SUCCESS)
-        return r;
+    return_state_if_error(r, _ESYS_STATE_INIT, "handle unknown.");
+
+    /* Initial invocation of SAPI to prepare the command buffer with parameters */
     r = Tss2_Sys_MakeCredential_Prepare(esysContext->sys,
                 (handleNode == NULL) ? TPM2_RH_NULL : handleNode->rsrc.handle,
                 credential,
                 objectName);
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error async MakeCredential");
-        return r;
-    }
-    r = init_session_tab(esysContext, shandle1, shandle2, shandle3);
-    return_if_error(r, "Initialize session resources");
+    return_state_if_error(r, _ESYS_STATE_INIT, "SAPI Prepare returned error.");
 
+    /* Calculate the cpHash Values */
+    r = init_session_tab(esysContext, shandle1, shandle2, shandle3);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Initialize session resources");
     iesys_compute_session_value(esysContext->session_tab[0], NULL, NULL);
     iesys_compute_session_value(esysContext->session_tab[1], NULL, NULL);
     iesys_compute_session_value(esysContext->session_tab[2], NULL, NULL);
-    r = iesys_gen_auths(esysContext, handleNode, NULL, NULL, &auths);
-    return_if_error(r, "Error in computation of auth values");
 
+    /* Generate the auth values and set them in the SAPI command buffer */
+    r = iesys_gen_auths(esysContext, handleNode, NULL, NULL, &auths);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Error in computation of auth values");
     esysContext->authsCount = auths.count;
     r = Tss2_Sys_SetCmdAuths(esysContext->sys, &auths);
-    if (r != TSS2_RC_SUCCESS) {
-        return r;
-    }
+    return_state_if_error(r, _ESYS_STATE_INIT, "SAPI error on SetCmdAuths");
 
+    /* Trigger execution and finish the async invocation */
     r = Tss2_Sys_ExecuteAsync(esysContext->sys);
-    return_if_error(r, "Finish (Execute Async)");
+    return_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Finish (Execute Async)");
 
     esysContext->state = _ESYS_STATE_SENT;
 
@@ -239,15 +243,20 @@
     TPM2B_ENCRYPTED_SECRET **secret)
 {
     LOG_TRACE("complete");
+    TSS2_RC r;
     if (esysContext == NULL) {
         LOG_ERROR("esyscontext is NULL.");
         return TSS2_ESYS_RC_BAD_REFERENCE;
     }
+
+    /* Check for correct sequence and set sequence to irregular for now */
     if (esysContext->state != _ESYS_STATE_SENT) {
         LOG_ERROR("Esys called in bad sequence.");
         return TSS2_ESYS_RC_BAD_SEQUENCE;
     }
-    TSS2_RC r;
+    esysContext->state = _ESYS_STATE_INTERNALERROR;
+
+    /* Allocate memory for response parameters */
     if (credentialBlob != NULL) {
         *credentialBlob = calloc(sizeof(TPM2B_ID_OBJECT), 1);
         if (*credentialBlob == NULL) {
@@ -260,17 +269,22 @@
             goto_error(r, TSS2_ESYS_RC_MEMORY, "Out of memory", error_cleanup);
         }
     }
+
+    /*Receive the TPM response and handle resubmissions if necessary. */
     r = Tss2_Sys_ExecuteFinish(esysContext->sys, esysContext->timeout);
     if ((r & ~TSS2_RC_LAYER_MASK) == TSS2_BASE_RC_TRY_AGAIN) {
         LOG_DEBUG("A layer below returned TRY_AGAIN: %" PRIx32, r);
+        esysContext->state = _ESYS_STATE_SENT;
         goto error_cleanup;
     }
+    /* This block handle the resubmission of TPM commands given a certain set of
+     * TPM response codes. */
     if (r == TPM2_RC_RETRY || r == TPM2_RC_TESTING || r == TPM2_RC_YIELDED) {
         LOG_DEBUG("TPM returned RETRY, TESTING or YIELDED, which triggers a "
             "resubmission: %" PRIx32, r);
         if (esysContext->submissionCount >= _ESYS_MAX_SUBMISSIONS) {
-            LOG_WARNING("Maximum number of resubmissions has been reached.");
-            esysContext->state = _ESYS_STATE_ERRORRESPONSE;
+            LOG_WARNING("Maximum number of (re)submissions has been reached.");
+            esysContext->state = _ESYS_STATE_INIT;
             goto error_cleanup;
         }
         esysContext->state = _ESYS_STATE_RESUBMISSION;
@@ -282,22 +296,32 @@
                 esysContext->in.MakeCredential.credential,
                 esysContext->in.MakeCredential.objectName);
         if (r != TSS2_RC_SUCCESS) {
-            LOG_ERROR("Error attempting to resubmit");
+            LOG_WARNING("Error attempting to resubmit");
+            /* We do not set esysContext->state here but inherit the most recent
+             * state of the _async function. */
             goto error_cleanup;
         }
         r = TSS2_ESYS_RC_TRY_AGAIN;
+        LOG_DEBUG("Resubmission initiated and returning RC_TRY_AGAIN.");
         goto error_cleanup;
     }
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error finish (ExecuteFinish) MakeCredential");
+    /* The following is the "regular error" handling. */
+    if (r != TSS2_RC_SUCCESS && (r & TSS2_RC_LAYER_MASK) == 0) {
+        LOG_WARNING("Received TPM Error");
+        esysContext->state = _ESYS_STATE_INIT;
+        goto error_cleanup;
+    } else if (r != TSS2_RC_SUCCESS) {
+        LOG_ERROR("Received a non-TPM Error");
+        esysContext->state = _ESYS_STATE_INTERNALERROR;
         goto error_cleanup;
     }
+
     /*
      * Now the verification of the response (hmac check) and if necessary the
-     * parameter decryption have to be done
+     * parameter decryption have to be done.
      */
     r = iesys_check_response(esysContext);
-    goto_if_error(r, "Error: check response",
+    goto_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Error: check response",
                       error_cleanup);
     /*
      * After the verification of the response we call the complete function
@@ -306,19 +330,19 @@
     r = Tss2_Sys_MakeCredential_Complete(esysContext->sys,
                 (credentialBlob != NULL) ? *credentialBlob : NULL,
                 (secret != NULL) ? *secret : NULL);
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error finish (ExecuteFinish) MakeCredential: %" PRIx32, r);
-        esysContext->state = _ESYS_STATE_ERRORRESPONSE;
-        goto error_cleanup;;
-    }
-    esysContext->state = _ESYS_STATE_FINISHED;
+    goto_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Received error from SAPI"
+                        " unmarshalling" ,error_cleanup);
+    esysContext->state = _ESYS_STATE_INIT;
+    LOG_DEBUG("context=%p, credentialBlob=%p, secret=%p",
+              esysContext, credentialBlob, secret);
 
-    return r;
+    return TSS2_RC_SUCCESS;
 
 error_cleanup:
     if (credentialBlob != NULL)
         SAFE_FREE(*credentialBlob);
     if (secret != NULL)
         SAFE_FREE(*secret);
+
     return r;
 }
diff --git a/src/tss2-esys/api/Esys_NV_Certify.c b/src/tss2-esys/api/Esys_NV_Certify.c
index 78d9599..d240935 100644
--- a/src/tss2-esys/api/Esys_NV_Certify.c
+++ b/src/tss2-esys/api/Esys_NV_Certify.c
@@ -203,6 +203,7 @@
     RSRC_NODE_T *authHandleNode;
     RSRC_NODE_T *nvIndexNode;
 
+    /* Check context, sequence correctness and set state to error for now */
     if (esysContext == NULL) {
         LOG_ERROR("esyscontext is NULL.");
         return TSS2_ESYS_RC_BAD_REFERENCE;
@@ -210,23 +211,26 @@
     r = iesys_check_sequence_async(esysContext);
     if (r != TSS2_RC_SUCCESS)
         return r;
-    r = check_session_feasability(shandle1, shandle2, shandle3, 1);
-    return_if_error(r, "Check session usage");
+    esysContext->state = _ESYS_STATE_INTERNALERROR;
 
+    /* Check and store input parameters */
+    r = check_session_feasability(shandle1, shandle2, shandle3, 1);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Check session usage");
     store_input_parameters(esysContext, signHandle, authHandle, nvIndex,
                 qualifyingData,
                 inScheme,
                 size,
                 offset);
+
+    /* Retrieve the metadata objects for provided handles */
     r = esys_GetResourceObject(esysContext, signHandle, &signHandleNode);
-    if (r != TPM2_RC_SUCCESS)
-        return r;
+    return_state_if_error(r, _ESYS_STATE_INIT, "signHandle unknown.");
     r = esys_GetResourceObject(esysContext, authHandle, &authHandleNode);
-    if (r != TPM2_RC_SUCCESS)
-        return r;
+    return_state_if_error(r, _ESYS_STATE_INIT, "authHandle unknown.");
     r = esys_GetResourceObject(esysContext, nvIndex, &nvIndexNode);
-    if (r != TPM2_RC_SUCCESS)
-        return r;
+    return_state_if_error(r, _ESYS_STATE_INIT, "nvIndex unknown.");
+
+    /* Initial invocation of SAPI to prepare the command buffer with parameters */
     r = Tss2_Sys_NV_Certify_Prepare(esysContext->sys,
                 (signHandleNode == NULL) ? TPM2_RH_NULL : signHandleNode->rsrc.handle,
                 (authHandleNode == NULL) ? TPM2_RH_NULL : authHandleNode->rsrc.handle,
@@ -235,29 +239,27 @@
                 inScheme,
                 size,
                 offset);
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error async NV_Certify");
-        return r;
-    }
-    r = init_session_tab(esysContext, shandle1, shandle2, shandle3);
-    return_if_error(r, "Initialize session resources");
+    return_state_if_error(r, _ESYS_STATE_INIT, "SAPI Prepare returned error.");
 
+    /* Calculate the cpHash Values */
+    r = init_session_tab(esysContext, shandle1, shandle2, shandle3);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Initialize session resources");
     iesys_compute_session_value(esysContext->session_tab[0],
                 &signHandleNode->rsrc.name, &signHandleNode->auth);
     iesys_compute_session_value(esysContext->session_tab[1],
                 &authHandleNode->rsrc.name, &authHandleNode->auth);
     iesys_compute_session_value(esysContext->session_tab[2], NULL, NULL);
-    r = iesys_gen_auths(esysContext, signHandleNode, authHandleNode, nvIndexNode, &auths);
-    return_if_error(r, "Error in computation of auth values");
 
+    /* Generate the auth values and set them in the SAPI command buffer */
+    r = iesys_gen_auths(esysContext, signHandleNode, authHandleNode, nvIndexNode, &auths);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Error in computation of auth values");
     esysContext->authsCount = auths.count;
     r = Tss2_Sys_SetCmdAuths(esysContext->sys, &auths);
-    if (r != TSS2_RC_SUCCESS) {
-        return r;
-    }
+    return_state_if_error(r, _ESYS_STATE_INIT, "SAPI error on SetCmdAuths");
 
+    /* Trigger execution and finish the async invocation */
     r = Tss2_Sys_ExecuteAsync(esysContext->sys);
-    return_if_error(r, "Finish (Execute Async)");
+    return_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Finish (Execute Async)");
 
     esysContext->state = _ESYS_STATE_SENT;
 
@@ -287,15 +289,20 @@
     TPMT_SIGNATURE **signature)
 {
     LOG_TRACE("complete");
+    TSS2_RC r;
     if (esysContext == NULL) {
         LOG_ERROR("esyscontext is NULL.");
         return TSS2_ESYS_RC_BAD_REFERENCE;
     }
+
+    /* Check for correct sequence and set sequence to irregular for now */
     if (esysContext->state != _ESYS_STATE_SENT) {
         LOG_ERROR("Esys called in bad sequence.");
         return TSS2_ESYS_RC_BAD_SEQUENCE;
     }
-    TSS2_RC r;
+    esysContext->state = _ESYS_STATE_INTERNALERROR;
+
+    /* Allocate memory for response parameters */
     if (certifyInfo != NULL) {
         *certifyInfo = calloc(sizeof(TPM2B_ATTEST), 1);
         if (*certifyInfo == NULL) {
@@ -308,17 +315,22 @@
             goto_error(r, TSS2_ESYS_RC_MEMORY, "Out of memory", error_cleanup);
         }
     }
+
+    /*Receive the TPM response and handle resubmissions if necessary. */
     r = Tss2_Sys_ExecuteFinish(esysContext->sys, esysContext->timeout);
     if ((r & ~TSS2_RC_LAYER_MASK) == TSS2_BASE_RC_TRY_AGAIN) {
         LOG_DEBUG("A layer below returned TRY_AGAIN: %" PRIx32, r);
+        esysContext->state = _ESYS_STATE_SENT;
         goto error_cleanup;
     }
+    /* This block handle the resubmission of TPM commands given a certain set of
+     * TPM response codes. */
     if (r == TPM2_RC_RETRY || r == TPM2_RC_TESTING || r == TPM2_RC_YIELDED) {
         LOG_DEBUG("TPM returned RETRY, TESTING or YIELDED, which triggers a "
             "resubmission: %" PRIx32, r);
         if (esysContext->submissionCount >= _ESYS_MAX_SUBMISSIONS) {
-            LOG_WARNING("Maximum number of resubmissions has been reached.");
-            esysContext->state = _ESYS_STATE_ERRORRESPONSE;
+            LOG_WARNING("Maximum number of (re)submissions has been reached.");
+            esysContext->state = _ESYS_STATE_INIT;
             goto error_cleanup;
         }
         esysContext->state = _ESYS_STATE_RESUBMISSION;
@@ -334,22 +346,32 @@
                 esysContext->in.NV_Certify.size,
                 esysContext->in.NV_Certify.offset);
         if (r != TSS2_RC_SUCCESS) {
-            LOG_ERROR("Error attempting to resubmit");
+            LOG_WARNING("Error attempting to resubmit");
+            /* We do not set esysContext->state here but inherit the most recent
+             * state of the _async function. */
             goto error_cleanup;
         }
         r = TSS2_ESYS_RC_TRY_AGAIN;
+        LOG_DEBUG("Resubmission initiated and returning RC_TRY_AGAIN.");
         goto error_cleanup;
     }
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error finish (ExecuteFinish) NV_Certify");
+    /* The following is the "regular error" handling. */
+    if (r != TSS2_RC_SUCCESS && (r & TSS2_RC_LAYER_MASK) == 0) {
+        LOG_WARNING("Received TPM Error");
+        esysContext->state = _ESYS_STATE_INIT;
+        goto error_cleanup;
+    } else if (r != TSS2_RC_SUCCESS) {
+        LOG_ERROR("Received a non-TPM Error");
+        esysContext->state = _ESYS_STATE_INTERNALERROR;
         goto error_cleanup;
     }
+
     /*
      * Now the verification of the response (hmac check) and if necessary the
-     * parameter decryption have to be done
+     * parameter decryption have to be done.
      */
     r = iesys_check_response(esysContext);
-    goto_if_error(r, "Error: check response",
+    goto_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Error: check response",
                       error_cleanup);
     /*
      * After the verification of the response we call the complete function
@@ -358,19 +380,19 @@
     r = Tss2_Sys_NV_Certify_Complete(esysContext->sys,
                 (certifyInfo != NULL) ? *certifyInfo : NULL,
                 (signature != NULL) ? *signature : NULL);
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error finish (ExecuteFinish) NV_Certify: %" PRIx32, r);
-        esysContext->state = _ESYS_STATE_ERRORRESPONSE;
-        goto error_cleanup;;
-    }
-    esysContext->state = _ESYS_STATE_FINISHED;
+    goto_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Received error from SAPI"
+                        " unmarshalling" ,error_cleanup);
+    esysContext->state = _ESYS_STATE_INIT;
+    LOG_DEBUG("context=%p, certifyInfo=%p, signature=%p",
+              esysContext, certifyInfo, signature);
 
-    return r;
+    return TSS2_RC_SUCCESS;
 
 error_cleanup:
     if (certifyInfo != NULL)
         SAFE_FREE(*certifyInfo);
     if (signature != NULL)
         SAFE_FREE(*signature);
+
     return r;
 }
diff --git a/src/tss2-esys/api/Esys_NV_ChangeAuth.c b/src/tss2-esys/api/Esys_NV_ChangeAuth.c
index 293a5cd..d9d8d74 100644
--- a/src/tss2-esys/api/Esys_NV_ChangeAuth.c
+++ b/src/tss2-esys/api/Esys_NV_ChangeAuth.c
@@ -148,6 +148,7 @@
     TSS2L_SYS_AUTH_COMMAND auths;
     RSRC_NODE_T *nvIndexNode;
 
+    /* Check context, sequence correctness and set state to error for now */
     if (esysContext == NULL) {
         LOG_ERROR("esyscontext is NULL.");
         return TSS2_ESYS_RC_BAD_REFERENCE;
@@ -155,38 +156,42 @@
     r = iesys_check_sequence_async(esysContext);
     if (r != TSS2_RC_SUCCESS)
         return r;
-    r = check_session_feasability(shandle1, shandle2, shandle3, 1);
-    return_if_error(r, "Check session usage");
+    esysContext->state = _ESYS_STATE_INTERNALERROR;
 
+    /* Check and store input parameters */
+    r = check_session_feasability(shandle1, shandle2, shandle3, 1);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Check session usage");
     store_input_parameters(esysContext, nvIndex,
                 newAuth);
+
+    /* Retrieve the metadata objects for provided handles */
     r = esys_GetResourceObject(esysContext, nvIndex, &nvIndexNode);
-    if (r != TPM2_RC_SUCCESS)
-        return r;
+    return_state_if_error(r, _ESYS_STATE_INIT, "nvIndex unknown.");
+
+    /* Initial invocation of SAPI to prepare the command buffer with parameters */
     r = Tss2_Sys_NV_ChangeAuth_Prepare(esysContext->sys,
                 (nvIndexNode == NULL) ? TPM2_RH_NULL : nvIndexNode->rsrc.handle,
                 newAuth);
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error async NV_ChangeAuth");
-        return r;
-    }
-    r = init_session_tab(esysContext, shandle1, shandle2, shandle3);
-    return_if_error(r, "Initialize session resources");
+    return_state_if_error(r, _ESYS_STATE_INIT, "SAPI Prepare returned error.");
 
+    /* Calculate the cpHash Values */
+    r = init_session_tab(esysContext, shandle1, shandle2, shandle3);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Initialize session resources");
     iesys_compute_session_value(esysContext->session_tab[0],
                 &nvIndexNode->rsrc.name, &nvIndexNode->auth);
     iesys_compute_session_value(esysContext->session_tab[1], NULL, NULL);
-    r = iesys_gen_auths(esysContext, nvIndexNode, NULL, NULL, &auths);
-    return_if_error(r, "Error in computation of auth values");
+    iesys_compute_session_value(esysContext->session_tab[2], NULL, NULL);
 
+    /* Generate the auth values and set them in the SAPI command buffer */
+    r = iesys_gen_auths(esysContext, nvIndexNode, NULL, NULL, &auths);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Error in computation of auth values");
     esysContext->authsCount = auths.count;
     r = Tss2_Sys_SetCmdAuths(esysContext->sys, &auths);
-    if (r != TSS2_RC_SUCCESS) {
-        return r;
-    }
+    return_state_if_error(r, _ESYS_STATE_INIT, "SAPI error on SetCmdAuths");
 
+    /* Trigger execution and finish the async invocation */
     r = Tss2_Sys_ExecuteAsync(esysContext->sys);
-    return_if_error(r, "Finish (Execute Async)");
+    return_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Finish (Execute Async)");
 
     esysContext->state = _ESYS_STATE_SENT;
 
@@ -213,26 +218,34 @@
     RSRC_NODE_T *nvIndexNode;
 
     LOG_TRACE("complete");
+    TSS2_RC r;
     if (esysContext == NULL) {
         LOG_ERROR("esyscontext is NULL.");
         return TSS2_ESYS_RC_BAD_REFERENCE;
     }
+
+    /* Check for correct sequence and set sequence to irregular for now */
     if (esysContext->state != _ESYS_STATE_SENT) {
         LOG_ERROR("Esys called in bad sequence.");
         return TSS2_ESYS_RC_BAD_SEQUENCE;
     }
-    TSS2_RC r;
+    esysContext->state = _ESYS_STATE_INTERNALERROR;
+
+    /*Receive the TPM response and handle resubmissions if necessary. */
     r = Tss2_Sys_ExecuteFinish(esysContext->sys, esysContext->timeout);
     if ((r & ~TSS2_RC_LAYER_MASK) == TSS2_BASE_RC_TRY_AGAIN) {
         LOG_DEBUG("A layer below returned TRY_AGAIN: %" PRIx32, r);
+        esysContext->state = _ESYS_STATE_SENT;
         return r;
     }
+    /* This block handle the resubmission of TPM commands given a certain set of
+     * TPM response codes. */
     if (r == TPM2_RC_RETRY || r == TPM2_RC_TESTING || r == TPM2_RC_YIELDED) {
         LOG_DEBUG("TPM returned RETRY, TESTING or YIELDED, which triggers a "
             "resubmission: %" PRIx32, r);
         if (esysContext->submissionCount >= _ESYS_MAX_SUBMISSIONS) {
-            LOG_WARNING("Maximum number of resubmissions has been reached.");
-            esysContext->state = _ESYS_STATE_ERRORRESPONSE;
+            LOG_WARNING("Maximum number of (re)submissions has been reached.");
+            esysContext->state = _ESYS_STATE_INIT;
             return r;
         }
         esysContext->state = _ESYS_STATE_RESUBMISSION;
@@ -243,14 +256,23 @@
                 esysContext->session_type[2],
                 esysContext->in.NV_ChangeAuth.newAuth);
         if (r != TSS2_RC_SUCCESS) {
-            LOG_ERROR("Error attempting to resubmit");
+            LOG_WARNING("Error attempting to resubmit");
+            /* We do not set esysContext->state here but inherit the most recent
+             * state of the _async function. */
             return r;
         }
         r = TSS2_ESYS_RC_TRY_AGAIN;
+        LOG_DEBUG("Resubmission initiated and returning RC_TRY_AGAIN.");
         return r;
     }
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error finish (ExecuteFinish) NV_ChangeAuth");
+    /* The following is the "regular error" handling. */
+    if (r != TSS2_RC_SUCCESS && (r & TSS2_RC_LAYER_MASK) == 0) {
+        LOG_WARNING("Received TPM Error");
+        esysContext->state = _ESYS_STATE_INIT;
+        return r;
+    } else if (r != TSS2_RC_SUCCESS) {
+        LOG_ERROR("Received a non-TPM Error");
+        esysContext->state = _ESYS_STATE_INTERNALERROR;
         return r;
     }
     /*
@@ -267,21 +289,20 @@
 
     /*
      * Now the verification of the response (hmac check) and if necessary the
-     * parameter decryption have to be done
+     * parameter decryption have to be done.
      */
     r = iesys_check_response(esysContext);
-    return_if_error(r, "Error: check response");
+    return_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Error: check response");
     /*
      * After the verification of the response we call the complete function
      * to deliver the result.
      */
     r = Tss2_Sys_NV_ChangeAuth_Complete(esysContext->sys);
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error finish (ExecuteFinish) NV_ChangeAuth: %" PRIx32, r);
-        esysContext->state = _ESYS_STATE_ERRORRESPONSE;
-        return r;;
-    }
-    esysContext->state = _ESYS_STATE_FINISHED;
+    return_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Received error from SAPI"
+                        " unmarshalling" );
+    esysContext->state = _ESYS_STATE_INIT;
+    LOG_DEBUG("context=%p",
+              esysContext);
 
-    return r;
+    return TSS2_RC_SUCCESS;
 }
diff --git a/src/tss2-esys/api/Esys_NV_DefineSpace.c b/src/tss2-esys/api/Esys_NV_DefineSpace.c
index a08aedc..7741701 100644
--- a/src/tss2-esys/api/Esys_NV_DefineSpace.c
+++ b/src/tss2-esys/api/Esys_NV_DefineSpace.c
@@ -164,6 +164,7 @@
     TSS2L_SYS_AUTH_COMMAND auths;
     RSRC_NODE_T *authHandleNode;
 
+    /* Check context, sequence correctness and set state to error for now */
     if (esysContext == NULL) {
         LOG_ERROR("esyscontext is NULL.");
         return TSS2_ESYS_RC_BAD_REFERENCE;
@@ -171,51 +172,54 @@
     r = iesys_check_sequence_async(esysContext);
     if (r != TSS2_RC_SUCCESS)
         return r;
+    esysContext->state = _ESYS_STATE_INTERNALERROR;
 
     /* Prevent creation of undeletable NV space */
     if (publicInfo != NULL &&
         (publicInfo->nvPublic.attributes & TPMA_NV_POLICY_DELETE) != 0 &&
         publicInfo->nvPublic.authPolicy.size == 0) {
         r = TSS2_ESYS_RC_BAD_VALUE;
-        LOG_ERROR("Preventing creation of undeletable NV index.");
+        LOG_ERROR("Error (async) NV_DefineSpace: %" PRIx32, r);
         esysContext->state = _ESYS_STATE_INIT;
         return r;
     }
-    r = check_session_feasability(shandle1, shandle2, shandle3, 1);
-    return_if_error(r, "Check session usage");
 
+    /* Check and store input parameters */
+    r = check_session_feasability(shandle1, shandle2, shandle3, 1);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Check session usage");
     store_input_parameters(esysContext, authHandle,
                 auth,
                 publicInfo);
+
+    /* Retrieve the metadata objects for provided handles */
     r = esys_GetResourceObject(esysContext, authHandle, &authHandleNode);
-    if (r != TPM2_RC_SUCCESS)
-        return r;
+    return_state_if_error(r, _ESYS_STATE_INIT, "authHandle unknown.");
+
+    /* Initial invocation of SAPI to prepare the command buffer with parameters */
     r = Tss2_Sys_NV_DefineSpace_Prepare(esysContext->sys,
                 (authHandleNode == NULL) ? TPM2_RH_NULL : authHandleNode->rsrc.handle,
                 auth,
                 publicInfo);
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error async NV_DefineSpace");
-        return r;
-    }
-    r = init_session_tab(esysContext, shandle1, shandle2, shandle3);
-    return_if_error(r, "Initialize session resources");
+    return_state_if_error(r, _ESYS_STATE_INIT, "SAPI Prepare returned error.");
 
+    /* Calculate the cpHash Values */
+    r = init_session_tab(esysContext, shandle1, shandle2, shandle3);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Initialize session resources");
     iesys_compute_session_value(esysContext->session_tab[0],
                 &authHandleNode->rsrc.name, &authHandleNode->auth);
     iesys_compute_session_value(esysContext->session_tab[1], NULL, NULL);
     iesys_compute_session_value(esysContext->session_tab[2], NULL, NULL);
-    r = iesys_gen_auths(esysContext, authHandleNode, NULL, NULL, &auths);
-    return_if_error(r, "Error in computation of auth values");
 
+    /* Generate the auth values and set them in the SAPI command buffer */
+    r = iesys_gen_auths(esysContext, authHandleNode, NULL, NULL, &auths);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Error in computation of auth values");
     esysContext->authsCount = auths.count;
     r = Tss2_Sys_SetCmdAuths(esysContext->sys, &auths);
-    if (r != TSS2_RC_SUCCESS) {
-        return r;
-    }
+    return_state_if_error(r, _ESYS_STATE_INIT, "SAPI error on SetCmdAuths");
 
+    /* Trigger execution and finish the async invocation */
     r = Tss2_Sys_ExecuteAsync(esysContext->sys);
-    return_if_error(r, "Finish (Execute Async)");
+    return_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Finish (Execute Async)");
 
     esysContext->state = _ESYS_STATE_SENT;
 
@@ -241,18 +245,22 @@
     ESYS_TR *nvHandle)
 {
     LOG_TRACE("complete");
+    TSS2_RC r;
     if (esysContext == NULL) {
         LOG_ERROR("esyscontext is NULL.");
         return TSS2_ESYS_RC_BAD_REFERENCE;
     }
+
+    /* Check for correct sequence and set sequence to irregular for now */
     if (esysContext->state != _ESYS_STATE_SENT) {
         LOG_ERROR("Esys called in bad sequence.");
         return TSS2_ESYS_RC_BAD_SEQUENCE;
     }
-    TSS2_RC r;
-    IESYS_RESOURCE *nvHandleRsrc = NULL;
+    esysContext->state = _ESYS_STATE_INTERNALERROR;
     RSRC_NODE_T *nvHandleNode = NULL;
 
+
+    /* Allocate memory for response parameters */
     if (nvHandle == NULL) {
         LOG_ERROR("Handle nvHandle may not be NULL");
         return TSS2_ESYS_RC_BAD_REFERENCE;
@@ -262,17 +270,22 @@
     if (r != TSS2_RC_SUCCESS)
         return r;
 
+
+    /*Receive the TPM response and handle resubmissions if necessary. */
     r = Tss2_Sys_ExecuteFinish(esysContext->sys, esysContext->timeout);
     if ((r & ~TSS2_RC_LAYER_MASK) == TSS2_BASE_RC_TRY_AGAIN) {
         LOG_DEBUG("A layer below returned TRY_AGAIN: %" PRIx32, r);
+        esysContext->state = _ESYS_STATE_SENT;
         goto error_cleanup;
     }
+    /* This block handle the resubmission of TPM commands given a certain set of
+     * TPM response codes. */
     if (r == TPM2_RC_RETRY || r == TPM2_RC_TESTING || r == TPM2_RC_YIELDED) {
         LOG_DEBUG("TPM returned RETRY, TESTING or YIELDED, which triggers a "
             "resubmission: %" PRIx32, r);
         if (esysContext->submissionCount >= _ESYS_MAX_SUBMISSIONS) {
-            LOG_WARNING("Maximum number of resubmissions has been reached.");
-            esysContext->state = _ESYS_STATE_ERRORRESPONSE;
+            LOG_WARNING("Maximum number of (re)submissions has been reached.");
+            esysContext->state = _ESYS_STATE_INIT;
             goto error_cleanup;
         }
         esysContext->state = _ESYS_STATE_RESUBMISSION;
@@ -284,39 +297,47 @@
                 esysContext->in.NV_DefineSpace.auth,
                 esysContext->in.NV_DefineSpace.publicInfo);
         if (r != TSS2_RC_SUCCESS) {
-            LOG_ERROR("Error attempting to resubmit");
+            LOG_WARNING("Error attempting to resubmit");
+            /* We do not set esysContext->state here but inherit the most recent
+             * state of the _async function. */
             goto error_cleanup;
         }
         r = TSS2_ESYS_RC_TRY_AGAIN;
+        LOG_DEBUG("Resubmission initiated and returning RC_TRY_AGAIN.");
         goto error_cleanup;
     }
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error finish (ExecuteFinish) NV_DefineSpace");
+    /* The following is the "regular error" handling. */
+    if (r != TSS2_RC_SUCCESS && (r & TSS2_RC_LAYER_MASK) == 0) {
+        LOG_WARNING("Received TPM Error");
+        esysContext->state = _ESYS_STATE_INIT;
+        goto error_cleanup;
+    } else if (r != TSS2_RC_SUCCESS) {
+        LOG_ERROR("Received a non-TPM Error");
+        esysContext->state = _ESYS_STATE_INTERNALERROR;
         goto error_cleanup;
     }
+
     /*
      * Now the verification of the response (hmac check) and if necessary the
-     * parameter decryption have to be done
+     * parameter decryption have to be done.
      */
     r = iesys_check_response(esysContext);
-    goto_if_error(r, "Error: check response",
+    goto_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Error: check response",
                       error_cleanup);
     /*
      * After the verification of the response we call the complete function
      * to deliver the result.
      */
     r = Tss2_Sys_NV_DefineSpace_Complete(esysContext->sys);
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error finish (ExecuteFinish) NV_DefineSpace: %" PRIx32, r);
-        esysContext->state = _ESYS_STATE_ERRORRESPONSE;
-        goto error_cleanup;;
-    }
+    goto_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Received error from SAPI"
+                        " unmarshalling" ,error_cleanup);
+    /* Update the meta data of the ESYS_TR object */
     nvHandleNode->rsrc.rsrcType = IESYSC_NV_RSRC;
     r = iesys_nv_get_name(esysContext->in.NV_DefineSpace.publicInfo,
                           &nvHandleNode->rsrc.name);
     if (r != TSS2_RC_SUCCESS) {
         LOG_ERROR("Error finish (ExecuteFinish) NV_DefineSpace: %" PRIx32, r);
-        esysContext->state = _ESYS_STATE_ERRORRESPONSE;
+        esysContext->state = _ESYS_STATE_INTERNALERROR;
         goto error_cleanup;
     }
     nvHandleNode->rsrc.handle =
@@ -324,11 +345,14 @@
     nvHandleNode->rsrc.misc.rsrc_nv_pub =
         *esysContext->in.NV_DefineSpace.publicInfo;
     nvHandleNode->auth = *esysContext->in.NV_DefineSpace.auth;
-    esysContext->state = _ESYS_STATE_FINISHED;
+    esysContext->state = _ESYS_STATE_INIT;
+    LOG_DEBUG("context=%p, nvHandle=%p",
+              esysContext, nvHandle);
 
-    return r;
+    return TSS2_RC_SUCCESS;
 
 error_cleanup:
     Esys_TR_Close(esysContext, nvHandle);
+
     return r;
 }
diff --git a/src/tss2-esys/api/Esys_NV_Extend.c b/src/tss2-esys/api/Esys_NV_Extend.c
index fc39029..9d8495a 100644
--- a/src/tss2-esys/api/Esys_NV_Extend.c
+++ b/src/tss2-esys/api/Esys_NV_Extend.c
@@ -158,6 +158,7 @@
     RSRC_NODE_T *authHandleNode;
     RSRC_NODE_T *nvIndexNode;
 
+    /* Check context, sequence correctness and set state to error for now */
     if (esysContext == NULL) {
         LOG_ERROR("esyscontext is NULL.");
         return TSS2_ESYS_RC_BAD_REFERENCE;
@@ -165,43 +166,45 @@
     r = iesys_check_sequence_async(esysContext);
     if (r != TSS2_RC_SUCCESS)
         return r;
-    r = check_session_feasability(shandle1, shandle2, shandle3, 1);
-    return_if_error(r, "Check session usage");
+    esysContext->state = _ESYS_STATE_INTERNALERROR;
 
+    /* Check and store input parameters */
+    r = check_session_feasability(shandle1, shandle2, shandle3, 1);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Check session usage");
     store_input_parameters(esysContext, authHandle, nvIndex,
                 data);
+
+    /* Retrieve the metadata objects for provided handles */
     r = esys_GetResourceObject(esysContext, authHandle, &authHandleNode);
-    if (r != TPM2_RC_SUCCESS)
-        return r;
+    return_state_if_error(r, _ESYS_STATE_INIT, "authHandle unknown.");
     r = esys_GetResourceObject(esysContext, nvIndex, &nvIndexNode);
-    if (r != TPM2_RC_SUCCESS)
-        return r;
+    return_state_if_error(r, _ESYS_STATE_INIT, "nvIndex unknown.");
+
+    /* Initial invocation of SAPI to prepare the command buffer with parameters */
     r = Tss2_Sys_NV_Extend_Prepare(esysContext->sys,
                 (authHandleNode == NULL) ? TPM2_RH_NULL : authHandleNode->rsrc.handle,
                 (nvIndexNode == NULL) ? TPM2_RH_NULL : nvIndexNode->rsrc.handle,
                 data);
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error async NV_Extend");
-        return r;
-    }
-    r = init_session_tab(esysContext, shandle1, shandle2, shandle3);
-    return_if_error(r, "Initialize session resources");
+    return_state_if_error(r, _ESYS_STATE_INIT, "SAPI Prepare returned error.");
 
+    /* Calculate the cpHash Values */
+    r = init_session_tab(esysContext, shandle1, shandle2, shandle3);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Initialize session resources");
     iesys_compute_session_value(esysContext->session_tab[0],
                 &authHandleNode->rsrc.name, &authHandleNode->auth);
     iesys_compute_session_value(esysContext->session_tab[1], NULL, NULL);
     iesys_compute_session_value(esysContext->session_tab[2], NULL, NULL);
-    r = iesys_gen_auths(esysContext, authHandleNode, nvIndexNode, NULL, &auths);
-    return_if_error(r, "Error in computation of auth values");
 
+    /* Generate the auth values and set them in the SAPI command buffer */
+    r = iesys_gen_auths(esysContext, authHandleNode, nvIndexNode, NULL, &auths);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Error in computation of auth values");
     esysContext->authsCount = auths.count;
     r = Tss2_Sys_SetCmdAuths(esysContext->sys, &auths);
-    if (r != TSS2_RC_SUCCESS) {
-        return r;
-    }
+    return_state_if_error(r, _ESYS_STATE_INIT, "SAPI error on SetCmdAuths");
 
+    /* Trigger execution and finish the async invocation */
     r = Tss2_Sys_ExecuteAsync(esysContext->sys);
-    return_if_error(r, "Finish (Execute Async)");
+    return_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Finish (Execute Async)");
 
     esysContext->state = _ESYS_STATE_SENT;
 
@@ -225,26 +228,34 @@
     ESYS_CONTEXT *esysContext)
 {
     LOG_TRACE("complete");
+    TSS2_RC r;
     if (esysContext == NULL) {
         LOG_ERROR("esyscontext is NULL.");
         return TSS2_ESYS_RC_BAD_REFERENCE;
     }
+
+    /* Check for correct sequence and set sequence to irregular for now */
     if (esysContext->state != _ESYS_STATE_SENT) {
         LOG_ERROR("Esys called in bad sequence.");
         return TSS2_ESYS_RC_BAD_SEQUENCE;
     }
-    TSS2_RC r;
+    esysContext->state = _ESYS_STATE_INTERNALERROR;
+
+    /*Receive the TPM response and handle resubmissions if necessary. */
     r = Tss2_Sys_ExecuteFinish(esysContext->sys, esysContext->timeout);
     if ((r & ~TSS2_RC_LAYER_MASK) == TSS2_BASE_RC_TRY_AGAIN) {
         LOG_DEBUG("A layer below returned TRY_AGAIN: %" PRIx32, r);
+        esysContext->state = _ESYS_STATE_SENT;
         return r;
     }
+    /* This block handle the resubmission of TPM commands given a certain set of
+     * TPM response codes. */
     if (r == TPM2_RC_RETRY || r == TPM2_RC_TESTING || r == TPM2_RC_YIELDED) {
         LOG_DEBUG("TPM returned RETRY, TESTING or YIELDED, which triggers a "
             "resubmission: %" PRIx32, r);
         if (esysContext->submissionCount >= _ESYS_MAX_SUBMISSIONS) {
-            LOG_WARNING("Maximum number of resubmissions has been reached.");
-            esysContext->state = _ESYS_STATE_ERRORRESPONSE;
+            LOG_WARNING("Maximum number of (re)submissions has been reached.");
+            esysContext->state = _ESYS_STATE_INIT;
             return r;
         }
         esysContext->state = _ESYS_STATE_RESUBMISSION;
@@ -256,33 +267,42 @@
                 esysContext->session_type[2],
                 esysContext->in.NV_Extend.data);
         if (r != TSS2_RC_SUCCESS) {
-            LOG_ERROR("Error attempting to resubmit");
+            LOG_WARNING("Error attempting to resubmit");
+            /* We do not set esysContext->state here but inherit the most recent
+             * state of the _async function. */
             return r;
         }
         r = TSS2_ESYS_RC_TRY_AGAIN;
+        LOG_DEBUG("Resubmission initiated and returning RC_TRY_AGAIN.");
         return r;
     }
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error finish (ExecuteFinish) NV_Extend");
+    /* The following is the "regular error" handling. */
+    if (r != TSS2_RC_SUCCESS && (r & TSS2_RC_LAYER_MASK) == 0) {
+        LOG_WARNING("Received TPM Error");
+        esysContext->state = _ESYS_STATE_INIT;
+        return r;
+    } else if (r != TSS2_RC_SUCCESS) {
+        LOG_ERROR("Received a non-TPM Error");
+        esysContext->state = _ESYS_STATE_INTERNALERROR;
         return r;
     }
+
     /*
      * Now the verification of the response (hmac check) and if necessary the
-     * parameter decryption have to be done
+     * parameter decryption have to be done.
      */
     r = iesys_check_response(esysContext);
-    return_if_error(r, "Error: check response");
+    return_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Error: check response");
     /*
      * After the verification of the response we call the complete function
      * to deliver the result.
      */
     r = Tss2_Sys_NV_Extend_Complete(esysContext->sys);
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error finish (ExecuteFinish) NV_Extend: %" PRIx32, r);
-        esysContext->state = _ESYS_STATE_ERRORRESPONSE;
-        return r;;
-    }
-    esysContext->state = _ESYS_STATE_FINISHED;
+    return_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Received error from SAPI"
+                        " unmarshalling" );
+    esysContext->state = _ESYS_STATE_INIT;
+    LOG_DEBUG("context=%p",
+              esysContext);
 
-    return r;
+    return TSS2_RC_SUCCESS;
 }
diff --git a/src/tss2-esys/api/Esys_NV_GlobalWriteLock.c b/src/tss2-esys/api/Esys_NV_GlobalWriteLock.c
index 34565f9..204c98d 100644
--- a/src/tss2-esys/api/Esys_NV_GlobalWriteLock.c
+++ b/src/tss2-esys/api/Esys_NV_GlobalWriteLock.c
@@ -135,6 +135,7 @@
     TSS2L_SYS_AUTH_COMMAND auths;
     RSRC_NODE_T *authHandleNode;
 
+    /* Check context, sequence correctness and set state to error for now */
     if (esysContext == NULL) {
         LOG_ERROR("esyscontext is NULL.");
         return TSS2_ESYS_RC_BAD_REFERENCE;
@@ -142,35 +143,40 @@
     r = iesys_check_sequence_async(esysContext);
     if (r != TSS2_RC_SUCCESS)
         return r;
-    r = check_session_feasability(shandle1, shandle2, shandle3, 1);
-    return_if_error(r, "Check session usage");
+    esysContext->state = _ESYS_STATE_INTERNALERROR;
 
+    /* Check and store input parameters */
+    r = check_session_feasability(shandle1, shandle2, shandle3, 1);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Check session usage");
     store_input_parameters(esysContext, authHandle);
+
+    /* Retrieve the metadata objects for provided handles */
     r = esys_GetResourceObject(esysContext, authHandle, &authHandleNode);
-    if (r != TPM2_RC_SUCCESS)
-        return r;
+    return_state_if_error(r, _ESYS_STATE_INIT, "authHandle unknown.");
+
+    /* Initial invocation of SAPI to prepare the command buffer with parameters */
     r = Tss2_Sys_NV_GlobalWriteLock_Prepare(esysContext->sys,
                 (authHandleNode == NULL) ? TPM2_RH_NULL : authHandleNode->rsrc.handle);
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error async NV_GlobalWriteLock");
-        return r;
-    }
-    r = init_session_tab(esysContext, shandle1, shandle2, shandle3);
-    return_if_error(r, "Initialize session resources");
+    return_state_if_error(r, _ESYS_STATE_INIT, "SAPI Prepare returned error.");
 
+    /* Calculate the cpHash Values */
+    r = init_session_tab(esysContext, shandle1, shandle2, shandle3);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Initialize session resources");
     iesys_compute_session_value(esysContext->session_tab[0],
                 &authHandleNode->rsrc.name, &authHandleNode->auth);
-    r = iesys_gen_auths(esysContext, authHandleNode, NULL, NULL, &auths);
-    return_if_error(r, "Error in computation of auth values");
+    iesys_compute_session_value(esysContext->session_tab[1], NULL, NULL);
+    iesys_compute_session_value(esysContext->session_tab[2], NULL, NULL);
 
+    /* Generate the auth values and set them in the SAPI command buffer */
+    r = iesys_gen_auths(esysContext, authHandleNode, NULL, NULL, &auths);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Error in computation of auth values");
     esysContext->authsCount = auths.count;
     r = Tss2_Sys_SetCmdAuths(esysContext->sys, &auths);
-    if (r != TSS2_RC_SUCCESS) {
-        return r;
-    }
+    return_state_if_error(r, _ESYS_STATE_INIT, "SAPI error on SetCmdAuths");
 
+    /* Trigger execution and finish the async invocation */
     r = Tss2_Sys_ExecuteAsync(esysContext->sys);
-    return_if_error(r, "Finish (Execute Async)");
+    return_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Finish (Execute Async)");
 
     esysContext->state = _ESYS_STATE_SENT;
 
@@ -194,26 +200,34 @@
     ESYS_CONTEXT *esysContext)
 {
     LOG_TRACE("complete");
+    TSS2_RC r;
     if (esysContext == NULL) {
         LOG_ERROR("esyscontext is NULL.");
         return TSS2_ESYS_RC_BAD_REFERENCE;
     }
+
+    /* Check for correct sequence and set sequence to irregular for now */
     if (esysContext->state != _ESYS_STATE_SENT) {
         LOG_ERROR("Esys called in bad sequence.");
         return TSS2_ESYS_RC_BAD_SEQUENCE;
     }
-    TSS2_RC r;
+    esysContext->state = _ESYS_STATE_INTERNALERROR;
+
+    /*Receive the TPM response and handle resubmissions if necessary. */
     r = Tss2_Sys_ExecuteFinish(esysContext->sys, esysContext->timeout);
     if ((r & ~TSS2_RC_LAYER_MASK) == TSS2_BASE_RC_TRY_AGAIN) {
         LOG_DEBUG("A layer below returned TRY_AGAIN: %" PRIx32, r);
+        esysContext->state = _ESYS_STATE_SENT;
         return r;
     }
+    /* This block handle the resubmission of TPM commands given a certain set of
+     * TPM response codes. */
     if (r == TPM2_RC_RETRY || r == TPM2_RC_TESTING || r == TPM2_RC_YIELDED) {
         LOG_DEBUG("TPM returned RETRY, TESTING or YIELDED, which triggers a "
             "resubmission: %" PRIx32, r);
         if (esysContext->submissionCount >= _ESYS_MAX_SUBMISSIONS) {
-            LOG_WARNING("Maximum number of resubmissions has been reached.");
-            esysContext->state = _ESYS_STATE_ERRORRESPONSE;
+            LOG_WARNING("Maximum number of (re)submissions has been reached.");
+            esysContext->state = _ESYS_STATE_INIT;
             return r;
         }
         esysContext->state = _ESYS_STATE_RESUBMISSION;
@@ -223,33 +237,42 @@
                 esysContext->session_type[1],
                 esysContext->session_type[2]);
         if (r != TSS2_RC_SUCCESS) {
-            LOG_ERROR("Error attempting to resubmit");
+            LOG_WARNING("Error attempting to resubmit");
+            /* We do not set esysContext->state here but inherit the most recent
+             * state of the _async function. */
             return r;
         }
         r = TSS2_ESYS_RC_TRY_AGAIN;
+        LOG_DEBUG("Resubmission initiated and returning RC_TRY_AGAIN.");
         return r;
     }
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error finish (ExecuteFinish) NV_GlobalWriteLock");
+    /* The following is the "regular error" handling. */
+    if (r != TSS2_RC_SUCCESS && (r & TSS2_RC_LAYER_MASK) == 0) {
+        LOG_WARNING("Received TPM Error");
+        esysContext->state = _ESYS_STATE_INIT;
+        return r;
+    } else if (r != TSS2_RC_SUCCESS) {
+        LOG_ERROR("Received a non-TPM Error");
+        esysContext->state = _ESYS_STATE_INTERNALERROR;
         return r;
     }
+
     /*
      * Now the verification of the response (hmac check) and if necessary the
-     * parameter decryption have to be done
+     * parameter decryption have to be done.
      */
     r = iesys_check_response(esysContext);
-    return_if_error(r, "Error: check response");
+    return_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Error: check response");
     /*
      * After the verification of the response we call the complete function
      * to deliver the result.
      */
     r = Tss2_Sys_NV_GlobalWriteLock_Complete(esysContext->sys);
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error finish (ExecuteFinish) NV_GlobalWriteLock: %" PRIx32, r);
-        esysContext->state = _ESYS_STATE_ERRORRESPONSE;
-        return r;;
-    }
-    esysContext->state = _ESYS_STATE_FINISHED;
+    return_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Received error from SAPI"
+                        " unmarshalling" );
+    esysContext->state = _ESYS_STATE_INIT;
+    LOG_DEBUG("context=%p",
+              esysContext);
 
-    return r;
+    return TSS2_RC_SUCCESS;
 }
diff --git a/src/tss2-esys/api/Esys_NV_Increment.c b/src/tss2-esys/api/Esys_NV_Increment.c
index 0665d59..5d803e9 100644
--- a/src/tss2-esys/api/Esys_NV_Increment.c
+++ b/src/tss2-esys/api/Esys_NV_Increment.c
@@ -145,6 +145,7 @@
     RSRC_NODE_T *authHandleNode;
     RSRC_NODE_T *nvIndexNode;
 
+    /* Check context, sequence correctness and set state to error for now */
     if (esysContext == NULL) {
         LOG_ERROR("esyscontext is NULL.");
         return TSS2_ESYS_RC_BAD_REFERENCE;
@@ -152,40 +153,43 @@
     r = iesys_check_sequence_async(esysContext);
     if (r != TSS2_RC_SUCCESS)
         return r;
-    r = check_session_feasability(shandle1, shandle2, shandle3, 1);
-    return_if_error(r, "Check session usage");
+    esysContext->state = _ESYS_STATE_INTERNALERROR;
 
+    /* Check and store input parameters */
+    r = check_session_feasability(shandle1, shandle2, shandle3, 1);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Check session usage");
     store_input_parameters(esysContext, authHandle, nvIndex);
+
+    /* Retrieve the metadata objects for provided handles */
     r = esys_GetResourceObject(esysContext, authHandle, &authHandleNode);
-    if (r != TPM2_RC_SUCCESS)
-        return r;
+    return_state_if_error(r, _ESYS_STATE_INIT, "authHandle unknown.");
     r = esys_GetResourceObject(esysContext, nvIndex, &nvIndexNode);
-    if (r != TPM2_RC_SUCCESS)
-        return r;
+    return_state_if_error(r, _ESYS_STATE_INIT, "nvIndex unknown.");
+
+    /* Initial invocation of SAPI to prepare the command buffer with parameters */
     r = Tss2_Sys_NV_Increment_Prepare(esysContext->sys,
                 (authHandleNode == NULL) ? TPM2_RH_NULL : authHandleNode->rsrc.handle,
                 (nvIndexNode == NULL) ? TPM2_RH_NULL : nvIndexNode->rsrc.handle);
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error async NV_Increment");
-        return r;
-    }
-    r = init_session_tab(esysContext, shandle1, shandle2, shandle3);
-    return_if_error(r, "Initialize session resources");
+    return_state_if_error(r, _ESYS_STATE_INIT, "SAPI Prepare returned error.");
 
+    /* Calculate the cpHash Values */
+    r = init_session_tab(esysContext, shandle1, shandle2, shandle3);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Initialize session resources");
     iesys_compute_session_value(esysContext->session_tab[0],
                 &authHandleNode->rsrc.name, &authHandleNode->auth);
     iesys_compute_session_value(esysContext->session_tab[1], NULL, NULL);
-    r = iesys_gen_auths(esysContext, authHandleNode, nvIndexNode, NULL, &auths);
-    return_if_error(r, "Error in computation of auth values");
+    iesys_compute_session_value(esysContext->session_tab[2], NULL, NULL);
 
+    /* Generate the auth values and set them in the SAPI command buffer */
+    r = iesys_gen_auths(esysContext, authHandleNode, nvIndexNode, NULL, &auths);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Error in computation of auth values");
     esysContext->authsCount = auths.count;
     r = Tss2_Sys_SetCmdAuths(esysContext->sys, &auths);
-    if (r != TSS2_RC_SUCCESS) {
-        return r;
-    }
+    return_state_if_error(r, _ESYS_STATE_INIT, "SAPI error on SetCmdAuths");
 
+    /* Trigger execution and finish the async invocation */
     r = Tss2_Sys_ExecuteAsync(esysContext->sys);
-    return_if_error(r, "Finish (Execute Async)");
+    return_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Finish (Execute Async)");
 
     esysContext->state = _ESYS_STATE_SENT;
 
@@ -209,26 +213,34 @@
     ESYS_CONTEXT *esysContext)
 {
     LOG_TRACE("complete");
+    TSS2_RC r;
     if (esysContext == NULL) {
         LOG_ERROR("esyscontext is NULL.");
         return TSS2_ESYS_RC_BAD_REFERENCE;
     }
+
+    /* Check for correct sequence and set sequence to irregular for now */
     if (esysContext->state != _ESYS_STATE_SENT) {
         LOG_ERROR("Esys called in bad sequence.");
         return TSS2_ESYS_RC_BAD_SEQUENCE;
     }
-    TSS2_RC r;
+    esysContext->state = _ESYS_STATE_INTERNALERROR;
+
+    /*Receive the TPM response and handle resubmissions if necessary. */
     r = Tss2_Sys_ExecuteFinish(esysContext->sys, esysContext->timeout);
     if ((r & ~TSS2_RC_LAYER_MASK) == TSS2_BASE_RC_TRY_AGAIN) {
         LOG_DEBUG("A layer below returned TRY_AGAIN: %" PRIx32, r);
+        esysContext->state = _ESYS_STATE_SENT;
         return r;
     }
+    /* This block handle the resubmission of TPM commands given a certain set of
+     * TPM response codes. */
     if (r == TPM2_RC_RETRY || r == TPM2_RC_TESTING || r == TPM2_RC_YIELDED) {
         LOG_DEBUG("TPM returned RETRY, TESTING or YIELDED, which triggers a "
             "resubmission: %" PRIx32, r);
         if (esysContext->submissionCount >= _ESYS_MAX_SUBMISSIONS) {
-            LOG_WARNING("Maximum number of resubmissions has been reached.");
-            esysContext->state = _ESYS_STATE_ERRORRESPONSE;
+            LOG_WARNING("Maximum number of (re)submissions has been reached.");
+            esysContext->state = _ESYS_STATE_INIT;
             return r;
         }
         esysContext->state = _ESYS_STATE_RESUBMISSION;
@@ -239,45 +251,55 @@
                 esysContext->session_type[1],
                 esysContext->session_type[2]);
         if (r != TSS2_RC_SUCCESS) {
-            LOG_ERROR("Error attempting to resubmit");
+            LOG_WARNING("Error attempting to resubmit");
+            /* We do not set esysContext->state here but inherit the most recent
+             * state of the _async function. */
             return r;
         }
         r = TSS2_ESYS_RC_TRY_AGAIN;
+        LOG_DEBUG("Resubmission initiated and returning RC_TRY_AGAIN.");
         return r;
     }
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error finish (ExecuteFinish) NV_Increment");
+    /* The following is the "regular error" handling. */
+    if (r != TSS2_RC_SUCCESS && (r & TSS2_RC_LAYER_MASK) == 0) {
+        LOG_WARNING("Received TPM Error");
+        esysContext->state = _ESYS_STATE_INIT;
+        return r;
+    } else if (r != TSS2_RC_SUCCESS) {
+        LOG_ERROR("Received a non-TPM Error");
+        esysContext->state = _ESYS_STATE_INTERNALERROR;
         return r;
     }
+
     /*
      * Now the verification of the response (hmac check) and if necessary the
-     * parameter decryption have to be done
+     * parameter decryption have to be done.
      */
     r = iesys_check_response(esysContext);
-    return_if_error(r, "Error: check response");
+    return_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Error: check response");
     /*
      * After the verification of the response we call the complete function
      * to deliver the result.
      */
     r = Tss2_Sys_NV_Increment_Complete(esysContext->sys);
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error finish (ExecuteFinish) NV_Increment: %" PRIx32, r);
-        esysContext->state = _ESYS_STATE_ERRORRESPONSE;
-        return r;;
-    }
+    return_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Received error from SAPI"
+                        " unmarshalling" );
 
     ESYS_TR nvIndex = esysContext->in.NV_Write.nvIndex;
         RSRC_NODE_T *nvIndexNode;
     r = esys_GetResourceObject(esysContext, nvIndex, &nvIndexNode);
     return_if_error(r, "get resource");
 
+    /* Update name in meta data because of possibly changed attributes */
     if (nvIndexNode != NULL) {
         nvIndexNode->rsrc.misc.rsrc_nv_pub.nvPublic.attributes |= TPMA_NV_WRITTEN;
         r = iesys_nv_get_name(&nvIndexNode->rsrc.misc.rsrc_nv_pub,
                               &nvIndexNode->rsrc.name);
         return_if_error(r, "Error get nvname")
      }
-    esysContext->state = _ESYS_STATE_FINISHED;
+    esysContext->state = _ESYS_STATE_INIT;
+    LOG_DEBUG("context=%p",
+              esysContext);
 
-    return r;
+    return TSS2_RC_SUCCESS;
 }
diff --git a/src/tss2-esys/api/Esys_NV_Read.c b/src/tss2-esys/api/Esys_NV_Read.c
index 8418155..5c65c1e 100644
--- a/src/tss2-esys/api/Esys_NV_Read.c
+++ b/src/tss2-esys/api/Esys_NV_Read.c
@@ -163,6 +163,7 @@
     RSRC_NODE_T *authHandleNode;
     RSRC_NODE_T *nvIndexNode;
 
+    /* Check context, sequence correctness and set state to error for now */
     if (esysContext == NULL) {
         LOG_ERROR("esyscontext is NULL.");
         return TSS2_ESYS_RC_BAD_REFERENCE;
@@ -170,45 +171,47 @@
     r = iesys_check_sequence_async(esysContext);
     if (r != TSS2_RC_SUCCESS)
         return r;
-    r = check_session_feasability(shandle1, shandle2, shandle3, 1);
-    return_if_error(r, "Check session usage");
+    esysContext->state = _ESYS_STATE_INTERNALERROR;
 
+    /* Check and store input parameters */
+    r = check_session_feasability(shandle1, shandle2, shandle3, 1);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Check session usage");
     store_input_parameters(esysContext, authHandle, nvIndex,
                 size,
                 offset);
+
+    /* Retrieve the metadata objects for provided handles */
     r = esys_GetResourceObject(esysContext, authHandle, &authHandleNode);
-    if (r != TPM2_RC_SUCCESS)
-        return r;
+    return_state_if_error(r, _ESYS_STATE_INIT, "authHandle unknown.");
     r = esys_GetResourceObject(esysContext, nvIndex, &nvIndexNode);
-    if (r != TPM2_RC_SUCCESS)
-        return r;
+    return_state_if_error(r, _ESYS_STATE_INIT, "nvIndex unknown.");
+
+    /* Initial invocation of SAPI to prepare the command buffer with parameters */
     r = Tss2_Sys_NV_Read_Prepare(esysContext->sys,
                 (authHandleNode == NULL) ? TPM2_RH_NULL : authHandleNode->rsrc.handle,
                 (nvIndexNode == NULL) ? TPM2_RH_NULL : nvIndexNode->rsrc.handle,
                 size,
                 offset);
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error async NV_Read");
-        return r;
-    }
-    r = init_session_tab(esysContext, shandle1, shandle2, shandle3);
-    return_if_error(r, "Initialize session resources");
+    return_state_if_error(r, _ESYS_STATE_INIT, "SAPI Prepare returned error.");
 
+    /* Calculate the cpHash Values */
+    r = init_session_tab(esysContext, shandle1, shandle2, shandle3);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Initialize session resources");
     iesys_compute_session_value(esysContext->session_tab[0],
                 &authHandleNode->rsrc.name, &authHandleNode->auth);
     iesys_compute_session_value(esysContext->session_tab[1], NULL, NULL);
     iesys_compute_session_value(esysContext->session_tab[2], NULL, NULL);
-    r = iesys_gen_auths(esysContext, authHandleNode, nvIndexNode, NULL, &auths);
-    return_if_error(r, "Error in computation of auth values");
 
+    /* Generate the auth values and set them in the SAPI command buffer */
+    r = iesys_gen_auths(esysContext, authHandleNode, nvIndexNode, NULL, &auths);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Error in computation of auth values");
     esysContext->authsCount = auths.count;
     r = Tss2_Sys_SetCmdAuths(esysContext->sys, &auths);
-    if (r != TSS2_RC_SUCCESS) {
-        return r;
-    }
+    return_state_if_error(r, _ESYS_STATE_INIT, "SAPI error on SetCmdAuths");
 
+    /* Trigger execution and finish the async invocation */
     r = Tss2_Sys_ExecuteAsync(esysContext->sys);
-    return_if_error(r, "Finish (Execute Async)");
+    return_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Finish (Execute Async)");
 
     esysContext->state = _ESYS_STATE_SENT;
 
@@ -235,32 +238,42 @@
     TPM2B_MAX_NV_BUFFER **data)
 {
     LOG_TRACE("complete");
+    TSS2_RC r;
     if (esysContext == NULL) {
         LOG_ERROR("esyscontext is NULL.");
         return TSS2_ESYS_RC_BAD_REFERENCE;
     }
+
+    /* Check for correct sequence and set sequence to irregular for now */
     if (esysContext->state != _ESYS_STATE_SENT) {
         LOG_ERROR("Esys called in bad sequence.");
         return TSS2_ESYS_RC_BAD_SEQUENCE;
     }
-    TSS2_RC r;
+    esysContext->state = _ESYS_STATE_INTERNALERROR;
+
+    /* Allocate memory for response parameters */
     if (data != NULL) {
         *data = calloc(sizeof(TPM2B_MAX_NV_BUFFER), 1);
         if (*data == NULL) {
             return_error(TSS2_ESYS_RC_MEMORY, "Out of memory");
         }
     }
+
+    /*Receive the TPM response and handle resubmissions if necessary. */
     r = Tss2_Sys_ExecuteFinish(esysContext->sys, esysContext->timeout);
     if ((r & ~TSS2_RC_LAYER_MASK) == TSS2_BASE_RC_TRY_AGAIN) {
         LOG_DEBUG("A layer below returned TRY_AGAIN: %" PRIx32, r);
+        esysContext->state = _ESYS_STATE_SENT;
         goto error_cleanup;
     }
+    /* This block handle the resubmission of TPM commands given a certain set of
+     * TPM response codes. */
     if (r == TPM2_RC_RETRY || r == TPM2_RC_TESTING || r == TPM2_RC_YIELDED) {
         LOG_DEBUG("TPM returned RETRY, TESTING or YIELDED, which triggers a "
             "resubmission: %" PRIx32, r);
         if (esysContext->submissionCount >= _ESYS_MAX_SUBMISSIONS) {
-            LOG_WARNING("Maximum number of resubmissions has been reached.");
-            esysContext->state = _ESYS_STATE_ERRORRESPONSE;
+            LOG_WARNING("Maximum number of (re)submissions has been reached.");
+            esysContext->state = _ESYS_STATE_INIT;
             goto error_cleanup;
         }
         esysContext->state = _ESYS_STATE_RESUBMISSION;
@@ -273,22 +286,32 @@
                 esysContext->in.NV_Read.size,
                 esysContext->in.NV_Read.offset);
         if (r != TSS2_RC_SUCCESS) {
-            LOG_ERROR("Error attempting to resubmit");
+            LOG_WARNING("Error attempting to resubmit");
+            /* We do not set esysContext->state here but inherit the most recent
+             * state of the _async function. */
             goto error_cleanup;
         }
         r = TSS2_ESYS_RC_TRY_AGAIN;
+        LOG_DEBUG("Resubmission initiated and returning RC_TRY_AGAIN.");
         goto error_cleanup;
     }
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error finish (ExecuteFinish) NV_Read");
+    /* The following is the "regular error" handling. */
+    if (r != TSS2_RC_SUCCESS && (r & TSS2_RC_LAYER_MASK) == 0) {
+        LOG_WARNING("Received TPM Error");
+        esysContext->state = _ESYS_STATE_INIT;
+        goto error_cleanup;
+    } else if (r != TSS2_RC_SUCCESS) {
+        LOG_ERROR("Received a non-TPM Error");
+        esysContext->state = _ESYS_STATE_INTERNALERROR;
         goto error_cleanup;
     }
+
     /*
      * Now the verification of the response (hmac check) and if necessary the
-     * parameter decryption have to be done
+     * parameter decryption have to be done.
      */
     r = iesys_check_response(esysContext);
-    goto_if_error(r, "Error: check response",
+    goto_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Error: check response",
                       error_cleanup);
     /*
      * After the verification of the response we call the complete function
@@ -296,17 +319,17 @@
      */
     r = Tss2_Sys_NV_Read_Complete(esysContext->sys,
                 (data != NULL) ? *data : NULL);
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error finish (ExecuteFinish) NV_Read: %" PRIx32, r);
-        esysContext->state = _ESYS_STATE_ERRORRESPONSE;
-        goto error_cleanup;;
-    }
-    esysContext->state = _ESYS_STATE_FINISHED;
+    goto_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Received error from SAPI"
+                        " unmarshalling" ,error_cleanup);
+    esysContext->state = _ESYS_STATE_INIT;
+    LOG_DEBUG("context=%p, data=%p",
+              esysContext, data);
 
-    return r;
+    return TSS2_RC_SUCCESS;
 
 error_cleanup:
     if (data != NULL)
         SAFE_FREE(*data);
+
     return r;
 }
diff --git a/src/tss2-esys/api/Esys_NV_ReadLock.c b/src/tss2-esys/api/Esys_NV_ReadLock.c
index c9be60a..92e3a64 100644
--- a/src/tss2-esys/api/Esys_NV_ReadLock.c
+++ b/src/tss2-esys/api/Esys_NV_ReadLock.c
@@ -145,6 +145,7 @@
     RSRC_NODE_T *authHandleNode;
     RSRC_NODE_T *nvIndexNode;
 
+    /* Check context, sequence correctness and set state to error for now */
     if (esysContext == NULL) {
         LOG_ERROR("esyscontext is NULL.");
         return TSS2_ESYS_RC_BAD_REFERENCE;
@@ -152,40 +153,43 @@
     r = iesys_check_sequence_async(esysContext);
     if (r != TSS2_RC_SUCCESS)
         return r;
-    r = check_session_feasability(shandle1, shandle2, shandle3, 1);
-    return_if_error(r, "Check session usage");
+    esysContext->state = _ESYS_STATE_INTERNALERROR;
 
+    /* Check and store input parameters */
+    r = check_session_feasability(shandle1, shandle2, shandle3, 1);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Check session usage");
     store_input_parameters(esysContext, authHandle, nvIndex);
+
+    /* Retrieve the metadata objects for provided handles */
     r = esys_GetResourceObject(esysContext, authHandle, &authHandleNode);
-    if (r != TPM2_RC_SUCCESS)
-        return r;
+    return_state_if_error(r, _ESYS_STATE_INIT, "authHandle unknown.");
     r = esys_GetResourceObject(esysContext, nvIndex, &nvIndexNode);
-    if (r != TPM2_RC_SUCCESS)
-        return r;
+    return_state_if_error(r, _ESYS_STATE_INIT, "nvIndex unknown.");
+
+    /* Initial invocation of SAPI to prepare the command buffer with parameters */
     r = Tss2_Sys_NV_ReadLock_Prepare(esysContext->sys,
                 (authHandleNode == NULL) ? TPM2_RH_NULL : authHandleNode->rsrc.handle,
                 (nvIndexNode == NULL) ? TPM2_RH_NULL : nvIndexNode->rsrc.handle);
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error async NV_ReadLock");
-        return r;
-    }
-    r = init_session_tab(esysContext, shandle1, shandle2, shandle3);
-    return_if_error(r, "Initialize session resources");
+    return_state_if_error(r, _ESYS_STATE_INIT, "SAPI Prepare returned error.");
 
+    /* Calculate the cpHash Values */
+    r = init_session_tab(esysContext, shandle1, shandle2, shandle3);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Initialize session resources");
     iesys_compute_session_value(esysContext->session_tab[0],
                 &authHandleNode->rsrc.name, &authHandleNode->auth);
     iesys_compute_session_value(esysContext->session_tab[1], NULL, NULL);
-    r = iesys_gen_auths(esysContext, authHandleNode, nvIndexNode, NULL, &auths);
-    return_if_error(r, "Error in computation of auth values");
+    iesys_compute_session_value(esysContext->session_tab[2], NULL, NULL);
 
+    /* Generate the auth values and set them in the SAPI command buffer */
+    r = iesys_gen_auths(esysContext, authHandleNode, nvIndexNode, NULL, &auths);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Error in computation of auth values");
     esysContext->authsCount = auths.count;
     r = Tss2_Sys_SetCmdAuths(esysContext->sys, &auths);
-    if (r != TSS2_RC_SUCCESS) {
-        return r;
-    }
+    return_state_if_error(r, _ESYS_STATE_INIT, "SAPI error on SetCmdAuths");
 
+    /* Trigger execution and finish the async invocation */
     r = Tss2_Sys_ExecuteAsync(esysContext->sys);
-    return_if_error(r, "Finish (Execute Async)");
+    return_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Finish (Execute Async)");
 
     esysContext->state = _ESYS_STATE_SENT;
 
@@ -209,26 +213,34 @@
     ESYS_CONTEXT *esysContext)
 {
     LOG_TRACE("complete");
+    TSS2_RC r;
     if (esysContext == NULL) {
         LOG_ERROR("esyscontext is NULL.");
         return TSS2_ESYS_RC_BAD_REFERENCE;
     }
+
+    /* Check for correct sequence and set sequence to irregular for now */
     if (esysContext->state != _ESYS_STATE_SENT) {
         LOG_ERROR("Esys called in bad sequence.");
         return TSS2_ESYS_RC_BAD_SEQUENCE;
     }
-    TSS2_RC r;
+    esysContext->state = _ESYS_STATE_INTERNALERROR;
+
+    /*Receive the TPM response and handle resubmissions if necessary. */
     r = Tss2_Sys_ExecuteFinish(esysContext->sys, esysContext->timeout);
     if ((r & ~TSS2_RC_LAYER_MASK) == TSS2_BASE_RC_TRY_AGAIN) {
         LOG_DEBUG("A layer below returned TRY_AGAIN: %" PRIx32, r);
+        esysContext->state = _ESYS_STATE_SENT;
         return r;
     }
+    /* This block handle the resubmission of TPM commands given a certain set of
+     * TPM response codes. */
     if (r == TPM2_RC_RETRY || r == TPM2_RC_TESTING || r == TPM2_RC_YIELDED) {
         LOG_DEBUG("TPM returned RETRY, TESTING or YIELDED, which triggers a "
             "resubmission: %" PRIx32, r);
         if (esysContext->submissionCount >= _ESYS_MAX_SUBMISSIONS) {
-            LOG_WARNING("Maximum number of resubmissions has been reached.");
-            esysContext->state = _ESYS_STATE_ERRORRESPONSE;
+            LOG_WARNING("Maximum number of (re)submissions has been reached.");
+            esysContext->state = _ESYS_STATE_INIT;
             return r;
         }
         esysContext->state = _ESYS_STATE_RESUBMISSION;
@@ -239,45 +251,55 @@
                 esysContext->session_type[1],
                 esysContext->session_type[2]);
         if (r != TSS2_RC_SUCCESS) {
-            LOG_ERROR("Error attempting to resubmit");
+            LOG_WARNING("Error attempting to resubmit");
+            /* We do not set esysContext->state here but inherit the most recent
+             * state of the _async function. */
             return r;
         }
         r = TSS2_ESYS_RC_TRY_AGAIN;
+        LOG_DEBUG("Resubmission initiated and returning RC_TRY_AGAIN.");
         return r;
     }
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error finish (ExecuteFinish) NV_ReadLock");
+    /* The following is the "regular error" handling. */
+    if (r != TSS2_RC_SUCCESS && (r & TSS2_RC_LAYER_MASK) == 0) {
+        LOG_WARNING("Received TPM Error");
+        esysContext->state = _ESYS_STATE_INIT;
+        return r;
+    } else if (r != TSS2_RC_SUCCESS) {
+        LOG_ERROR("Received a non-TPM Error");
+        esysContext->state = _ESYS_STATE_INTERNALERROR;
         return r;
     }
+
     /*
      * Now the verification of the response (hmac check) and if necessary the
-     * parameter decryption have to be done
+     * parameter decryption have to be done.
      */
     r = iesys_check_response(esysContext);
-    return_if_error(r, "Error: check response");
+    return_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Error: check response");
     /*
      * After the verification of the response we call the complete function
      * to deliver the result.
      */
     r = Tss2_Sys_NV_ReadLock_Complete(esysContext->sys);
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error finish (ExecuteFinish) NV_ReadLock: %" PRIx32, r);
-        esysContext->state = _ESYS_STATE_ERRORRESPONSE;
-        return r;;
-    }
+    return_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Received error from SAPI"
+                        " unmarshalling" );
 
     ESYS_TR nvIndex = esysContext->in.NV_Write.nvIndex;
-    RSRC_NODE_T *nvIndexNode;
+        RSRC_NODE_T *nvIndexNode;
     r = esys_GetResourceObject(esysContext, nvIndex, &nvIndexNode);
     return_if_error(r, "get resource");
 
+    /* Update name in meta data because of possibly changed attributes */
     if (nvIndexNode != NULL) {
         nvIndexNode->rsrc.misc.rsrc_nv_pub.nvPublic.attributes |=  TPMA_NV_READLOCKED;
         r = iesys_nv_get_name(&nvIndexNode->rsrc.misc.rsrc_nv_pub,
                               &nvIndexNode->rsrc.name);
         return_if_error(r, "Error get nvname")
      }
-    esysContext->state = _ESYS_STATE_FINISHED;
+    esysContext->state = _ESYS_STATE_INIT;
+    LOG_DEBUG("context=%p",
+              esysContext);
 
-    return r;
+    return TSS2_RC_SUCCESS;
 }
diff --git a/src/tss2-esys/api/Esys_NV_ReadPublic.c b/src/tss2-esys/api/Esys_NV_ReadPublic.c
index a7737bb..0688d4e 100644
--- a/src/tss2-esys/api/Esys_NV_ReadPublic.c
+++ b/src/tss2-esys/api/Esys_NV_ReadPublic.c
@@ -143,6 +143,7 @@
     TSS2L_SYS_AUTH_COMMAND auths;
     RSRC_NODE_T *nvIndexNode;
 
+    /* Check context, sequence correctness and set state to error for now */
     if (esysContext == NULL) {
         LOG_ERROR("esyscontext is NULL.");
         return TSS2_ESYS_RC_BAD_REFERENCE;
@@ -150,34 +151,39 @@
     r = iesys_check_sequence_async(esysContext);
     if (r != TSS2_RC_SUCCESS)
         return r;
-    r = check_session_feasability(shandle1, shandle2, shandle3, 0);
-    return_if_error(r, "Check session usage");
+    esysContext->state = _ESYS_STATE_INTERNALERROR;
 
+    /* Check and store input parameters */
+    r = check_session_feasability(shandle1, shandle2, shandle3, 0);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Check session usage");
     store_input_parameters(esysContext, nvIndex);
+
+    /* Retrieve the metadata objects for provided handles */
     r = esys_GetResourceObject(esysContext, nvIndex, &nvIndexNode);
-    if (r != TPM2_RC_SUCCESS)
-        return r;
+    return_state_if_error(r, _ESYS_STATE_INIT, "nvIndex unknown.");
+
+    /* Initial invocation of SAPI to prepare the command buffer with parameters */
     r = Tss2_Sys_NV_ReadPublic_Prepare(esysContext->sys,
                 (nvIndexNode == NULL) ? TPM2_RH_NULL : nvIndexNode->rsrc.handle);
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error async NV_ReadPublic");
-        return r;
-    }
+    return_state_if_error(r, _ESYS_STATE_INIT, "SAPI Prepare returned error.");
+
+    /* Calculate the cpHash Values */
     r = init_session_tab(esysContext, shandle1, shandle2, shandle3);
-    return_if_error(r, "Initialize session resources");
-
+    return_state_if_error(r, _ESYS_STATE_INIT, "Initialize session resources");
     iesys_compute_session_value(esysContext->session_tab[0], NULL, NULL);
-    r = iesys_gen_auths(esysContext, nvIndexNode, NULL, NULL, &auths);
-    return_if_error(r, "Error in computation of auth values");
+    iesys_compute_session_value(esysContext->session_tab[1], NULL, NULL);
+    iesys_compute_session_value(esysContext->session_tab[2], NULL, NULL);
 
+    /* Generate the auth values and set them in the SAPI command buffer */
+    r = iesys_gen_auths(esysContext, nvIndexNode, NULL, NULL, &auths);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Error in computation of auth values");
     esysContext->authsCount = auths.count;
     r = Tss2_Sys_SetCmdAuths(esysContext->sys, &auths);
-    if (r != TSS2_RC_SUCCESS) {
-        return r;
-    }
+    return_state_if_error(r, _ESYS_STATE_INIT, "SAPI error on SetCmdAuths");
 
+    /* Trigger execution and finish the async invocation */
     r = Tss2_Sys_ExecuteAsync(esysContext->sys);
-    return_if_error(r, "Finish (Execute Async)");
+    return_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Finish (Execute Async)");
 
     esysContext->state = _ESYS_STATE_SENT;
 
@@ -209,15 +215,20 @@
     TPM2B_NV_PUBLIC *lnvPublic = NULL;
     TPM2B_NAME *lnvName = NULL;
     LOG_TRACE("complete");
+    TSS2_RC r;
     if (esysContext == NULL) {
         LOG_ERROR("esyscontext is NULL.");
         return TSS2_ESYS_RC_BAD_REFERENCE;
     }
+
+    /* Check for correct sequence and set sequence to irregular for now */
     if (esysContext->state != _ESYS_STATE_SENT) {
         LOG_ERROR("Esys called in bad sequence.");
         return TSS2_ESYS_RC_BAD_SEQUENCE;
     }
-    TSS2_RC r;
+    esysContext->state = _ESYS_STATE_INTERNALERROR;
+
+    /* Allocate memory for response parameters */
     lnvPublic = calloc(sizeof(TPM2B_NV_PUBLIC), 1);
     if (lnvPublic == NULL) {
         return_error(TSS2_ESYS_RC_MEMORY, "Out of memory");
@@ -226,17 +237,22 @@
     if (lnvName == NULL) {
         goto_error(r, TSS2_ESYS_RC_MEMORY, "Out of memory", error_cleanup);
     }
+
+    /*Receive the TPM response and handle resubmissions if necessary. */
     r = Tss2_Sys_ExecuteFinish(esysContext->sys, esysContext->timeout);
     if ((r & ~TSS2_RC_LAYER_MASK) == TSS2_BASE_RC_TRY_AGAIN) {
         LOG_DEBUG("A layer below returned TRY_AGAIN: %" PRIx32, r);
+        esysContext->state = _ESYS_STATE_SENT;
         goto error_cleanup;
     }
+    /* This block handle the resubmission of TPM commands given a certain set of
+     * TPM response codes. */
     if (r == TPM2_RC_RETRY || r == TPM2_RC_TESTING || r == TPM2_RC_YIELDED) {
         LOG_DEBUG("TPM returned RETRY, TESTING or YIELDED, which triggers a "
             "resubmission: %" PRIx32, r);
         if (esysContext->submissionCount >= _ESYS_MAX_SUBMISSIONS) {
-            LOG_WARNING("Maximum number of resubmissions has been reached.");
-            esysContext->state = _ESYS_STATE_ERRORRESPONSE;
+            LOG_WARNING("Maximum number of (re)submissions has been reached.");
+            esysContext->state = _ESYS_STATE_INIT;
             goto error_cleanup;
         }
         esysContext->state = _ESYS_STATE_RESUBMISSION;
@@ -246,22 +262,32 @@
                 esysContext->session_type[1],
                 esysContext->session_type[2]);
         if (r != TSS2_RC_SUCCESS) {
-            LOG_ERROR("Error attempting to resubmit");
+            LOG_WARNING("Error attempting to resubmit");
+            /* We do not set esysContext->state here but inherit the most recent
+             * state of the _async function. */
             goto error_cleanup;
         }
         r = TSS2_ESYS_RC_TRY_AGAIN;
+        LOG_DEBUG("Resubmission initiated and returning RC_TRY_AGAIN.");
         goto error_cleanup;
     }
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error finish (ExecuteFinish) NV_ReadPublic");
+    /* The following is the "regular error" handling. */
+    if (r != TSS2_RC_SUCCESS && (r & TSS2_RC_LAYER_MASK) == 0) {
+        LOG_WARNING("Received TPM Error");
+        esysContext->state = _ESYS_STATE_INIT;
+        goto error_cleanup;
+    } else if (r != TSS2_RC_SUCCESS) {
+        LOG_ERROR("Received a non-TPM Error");
+        esysContext->state = _ESYS_STATE_INTERNALERROR;
         goto error_cleanup;
     }
+
     /*
      * Now the verification of the response (hmac check) and if necessary the
-     * parameter decryption have to be done
+     * parameter decryption have to be done.
      */
     r = iesys_check_response(esysContext);
-    goto_if_error(r, "Error: check response",
+    goto_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Error: check response",
                       error_cleanup);
     /*
      * After the verification of the response we call the complete function
@@ -270,12 +296,10 @@
     r = Tss2_Sys_NV_ReadPublic_Complete(esysContext->sys,
                 lnvPublic,
                 lnvName);
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error finish (ExecuteFinish) NV_ReadPublic: %" PRIx32, r);
-        esysContext->state = _ESYS_STATE_ERRORRESPONSE;
-        goto error_cleanup;;
-    }
+    goto_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Received error from SAPI"
+                        " unmarshalling" ,error_cleanup);
 
+    /* Update the meta data of the ESYS_TR object */
     ESYS_TR nvIndex = esysContext->in.NV_ReadPublic.nvIndex;
     RSRC_NODE_T *nvIndexNode;
     r = esys_GetResourceObject(esysContext, nvIndex, &nvIndexNode);
@@ -296,12 +320,15 @@
     else
         SAFE_FREE(lnvName);
 
-    esysContext->state = _ESYS_STATE_FINISHED;
+    esysContext->state = _ESYS_STATE_INIT;
+    LOG_DEBUG("context=%p, nvPublic=%p, nvName=%p",
+              esysContext, nvPublic, nvName);
 
-    return r;
+    return TSS2_RC_SUCCESS;
 
 error_cleanup:
     SAFE_FREE(lnvPublic);
     SAFE_FREE(lnvName);
+
     return r;
 }
diff --git a/src/tss2-esys/api/Esys_NV_SetBits.c b/src/tss2-esys/api/Esys_NV_SetBits.c
index af00a29..824948e 100644
--- a/src/tss2-esys/api/Esys_NV_SetBits.c
+++ b/src/tss2-esys/api/Esys_NV_SetBits.c
@@ -152,6 +152,7 @@
     RSRC_NODE_T *authHandleNode;
     RSRC_NODE_T *nvIndexNode;
 
+    /* Check context, sequence correctness and set state to error for now */
     if (esysContext == NULL) {
         LOG_ERROR("esyscontext is NULL.");
         return TSS2_ESYS_RC_BAD_REFERENCE;
@@ -159,43 +160,45 @@
     r = iesys_check_sequence_async(esysContext);
     if (r != TSS2_RC_SUCCESS)
         return r;
-    r = check_session_feasability(shandle1, shandle2, shandle3, 1);
-    return_if_error(r, "Check session usage");
+    esysContext->state = _ESYS_STATE_INTERNALERROR;
 
+    /* Check and store input parameters */
+    r = check_session_feasability(shandle1, shandle2, shandle3, 1);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Check session usage");
     store_input_parameters(esysContext, authHandle, nvIndex,
                 bits);
+
+    /* Retrieve the metadata objects for provided handles */
     r = esys_GetResourceObject(esysContext, authHandle, &authHandleNode);
-    if (r != TPM2_RC_SUCCESS)
-        return r;
+    return_state_if_error(r, _ESYS_STATE_INIT, "authHandle unknown.");
     r = esys_GetResourceObject(esysContext, nvIndex, &nvIndexNode);
-    if (r != TPM2_RC_SUCCESS)
-        return r;
+    return_state_if_error(r, _ESYS_STATE_INIT, "nvIndex unknown.");
+
+    /* Initial invocation of SAPI to prepare the command buffer with parameters */
     r = Tss2_Sys_NV_SetBits_Prepare(esysContext->sys,
                 (authHandleNode == NULL) ? TPM2_RH_NULL : authHandleNode->rsrc.handle,
                 (nvIndexNode == NULL) ? TPM2_RH_NULL : nvIndexNode->rsrc.handle,
                 bits);
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error async NV_SetBits");
-        return r;
-    }
-    r = init_session_tab(esysContext, shandle1, shandle2, shandle3);
-    return_if_error(r, "Initialize session resources");
+    return_state_if_error(r, _ESYS_STATE_INIT, "SAPI Prepare returned error.");
 
+    /* Calculate the cpHash Values */
+    r = init_session_tab(esysContext, shandle1, shandle2, shandle3);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Initialize session resources");
     iesys_compute_session_value(esysContext->session_tab[0],
                 &authHandleNode->rsrc.name, &authHandleNode->auth);
     iesys_compute_session_value(esysContext->session_tab[1], NULL, NULL);
     iesys_compute_session_value(esysContext->session_tab[2], NULL, NULL);
-    r = iesys_gen_auths(esysContext, authHandleNode, nvIndexNode, NULL, &auths);
-    return_if_error(r, "Error in computation of auth values");
 
+    /* Generate the auth values and set them in the SAPI command buffer */
+    r = iesys_gen_auths(esysContext, authHandleNode, nvIndexNode, NULL, &auths);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Error in computation of auth values");
     esysContext->authsCount = auths.count;
     r = Tss2_Sys_SetCmdAuths(esysContext->sys, &auths);
-    if (r != TSS2_RC_SUCCESS) {
-        return r;
-    }
+    return_state_if_error(r, _ESYS_STATE_INIT, "SAPI error on SetCmdAuths");
 
+    /* Trigger execution and finish the async invocation */
     r = Tss2_Sys_ExecuteAsync(esysContext->sys);
-    return_if_error(r, "Finish (Execute Async)");
+    return_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Finish (Execute Async)");
 
     esysContext->state = _ESYS_STATE_SENT;
 
@@ -219,26 +222,34 @@
     ESYS_CONTEXT *esysContext)
 {
     LOG_TRACE("complete");
+    TSS2_RC r;
     if (esysContext == NULL) {
         LOG_ERROR("esyscontext is NULL.");
         return TSS2_ESYS_RC_BAD_REFERENCE;
     }
+
+    /* Check for correct sequence and set sequence to irregular for now */
     if (esysContext->state != _ESYS_STATE_SENT) {
         LOG_ERROR("Esys called in bad sequence.");
         return TSS2_ESYS_RC_BAD_SEQUENCE;
     }
-    TSS2_RC r;
+    esysContext->state = _ESYS_STATE_INTERNALERROR;
+
+    /*Receive the TPM response and handle resubmissions if necessary. */
     r = Tss2_Sys_ExecuteFinish(esysContext->sys, esysContext->timeout);
     if ((r & ~TSS2_RC_LAYER_MASK) == TSS2_BASE_RC_TRY_AGAIN) {
         LOG_DEBUG("A layer below returned TRY_AGAIN: %" PRIx32, r);
+        esysContext->state = _ESYS_STATE_SENT;
         return r;
     }
+    /* This block handle the resubmission of TPM commands given a certain set of
+     * TPM response codes. */
     if (r == TPM2_RC_RETRY || r == TPM2_RC_TESTING || r == TPM2_RC_YIELDED) {
         LOG_DEBUG("TPM returned RETRY, TESTING or YIELDED, which triggers a "
             "resubmission: %" PRIx32, r);
         if (esysContext->submissionCount >= _ESYS_MAX_SUBMISSIONS) {
-            LOG_WARNING("Maximum number of resubmissions has been reached.");
-            esysContext->state = _ESYS_STATE_ERRORRESPONSE;
+            LOG_WARNING("Maximum number of (re)submissions has been reached.");
+            esysContext->state = _ESYS_STATE_INIT;
             return r;
         }
         esysContext->state = _ESYS_STATE_RESUBMISSION;
@@ -250,45 +261,55 @@
                 esysContext->session_type[2],
                 esysContext->in.NV_SetBits.bits);
         if (r != TSS2_RC_SUCCESS) {
-            LOG_ERROR("Error attempting to resubmit");
+            LOG_WARNING("Error attempting to resubmit");
+            /* We do not set esysContext->state here but inherit the most recent
+             * state of the _async function. */
             return r;
         }
         r = TSS2_ESYS_RC_TRY_AGAIN;
+        LOG_DEBUG("Resubmission initiated and returning RC_TRY_AGAIN.");
         return r;
     }
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error finish (ExecuteFinish) NV_SetBits");
+    /* The following is the "regular error" handling. */
+    if (r != TSS2_RC_SUCCESS && (r & TSS2_RC_LAYER_MASK) == 0) {
+        LOG_WARNING("Received TPM Error");
+        esysContext->state = _ESYS_STATE_INIT;
+        return r;
+    } else if (r != TSS2_RC_SUCCESS) {
+        LOG_ERROR("Received a non-TPM Error");
+        esysContext->state = _ESYS_STATE_INTERNALERROR;
         return r;
     }
+
     /*
      * Now the verification of the response (hmac check) and if necessary the
-     * parameter decryption have to be done
+     * parameter decryption have to be done.
      */
     r = iesys_check_response(esysContext);
-    return_if_error(r, "Error: check response");
+    return_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Error: check response");
     /*
      * After the verification of the response we call the complete function
      * to deliver the result.
      */
     r = Tss2_Sys_NV_SetBits_Complete(esysContext->sys);
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error finish (ExecuteFinish) NV_SetBits: %" PRIx32, r);
-        esysContext->state = _ESYS_STATE_ERRORRESPONSE;
-        return r;;
-    }
+    return_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Received error from SAPI"
+                        " unmarshalling" );
 
     ESYS_TR nvIndex = esysContext->in.NV_Write.nvIndex;
         RSRC_NODE_T *nvIndexNode;
     r = esys_GetResourceObject(esysContext, nvIndex, &nvIndexNode);
     return_if_error(r, "get resource");
 
+    /* Update name in meta data because of possibly changed attributes */
     if (nvIndexNode != NULL) {
         nvIndexNode->rsrc.misc.rsrc_nv_pub.nvPublic.attributes |= TPMA_NV_WRITTEN;
         r = iesys_nv_get_name(&nvIndexNode->rsrc.misc.rsrc_nv_pub,
                               &nvIndexNode->rsrc.name);
         return_if_error(r, "Error get nvname")
      }
-    esysContext->state = _ESYS_STATE_FINISHED;
+    esysContext->state = _ESYS_STATE_INIT;
+    LOG_DEBUG("context=%p",
+              esysContext);
 
-    return r;
+    return TSS2_RC_SUCCESS;
 }
diff --git a/src/tss2-esys/api/Esys_NV_UndefineSpace.c b/src/tss2-esys/api/Esys_NV_UndefineSpace.c
index 173b391..3930a79 100644
--- a/src/tss2-esys/api/Esys_NV_UndefineSpace.c
+++ b/src/tss2-esys/api/Esys_NV_UndefineSpace.c
@@ -145,6 +145,7 @@
     RSRC_NODE_T *authHandleNode;
     RSRC_NODE_T *nvIndexNode;
 
+    /* Check context, sequence correctness and set state to error for now */
     if (esysContext == NULL) {
         LOG_ERROR("esyscontext is NULL.");
         return TSS2_ESYS_RC_BAD_REFERENCE;
@@ -152,40 +153,43 @@
     r = iesys_check_sequence_async(esysContext);
     if (r != TSS2_RC_SUCCESS)
         return r;
-    r = check_session_feasability(shandle1, shandle2, shandle3, 1);
-    return_if_error(r, "Check session usage");
+    esysContext->state = _ESYS_STATE_INTERNALERROR;
 
+    /* Check and store input parameters */
+    r = check_session_feasability(shandle1, shandle2, shandle3, 1);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Check session usage");
     store_input_parameters(esysContext, authHandle, nvIndex);
+
+    /* Retrieve the metadata objects for provided handles */
     r = esys_GetResourceObject(esysContext, authHandle, &authHandleNode);
-    if (r != TPM2_RC_SUCCESS)
-        return r;
+    return_state_if_error(r, _ESYS_STATE_INIT, "authHandle unknown.");
     r = esys_GetResourceObject(esysContext, nvIndex, &nvIndexNode);
-    if (r != TPM2_RC_SUCCESS)
-        return r;
+    return_state_if_error(r, _ESYS_STATE_INIT, "nvIndex unknown.");
+
+    /* Initial invocation of SAPI to prepare the command buffer with parameters */
     r = Tss2_Sys_NV_UndefineSpace_Prepare(esysContext->sys,
                 (authHandleNode == NULL) ? TPM2_RH_NULL : authHandleNode->rsrc.handle,
                 (nvIndexNode == NULL) ? TPM2_RH_NULL : nvIndexNode->rsrc.handle);
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error async NV_UndefineSpace");
-        return r;
-    }
-    r = init_session_tab(esysContext, shandle1, shandle2, shandle3);
-    return_if_error(r, "Initialize session resources");
+    return_state_if_error(r, _ESYS_STATE_INIT, "SAPI Prepare returned error.");
 
+    /* Calculate the cpHash Values */
+    r = init_session_tab(esysContext, shandle1, shandle2, shandle3);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Initialize session resources");
     iesys_compute_session_value(esysContext->session_tab[0],
                 &authHandleNode->rsrc.name, &authHandleNode->auth);
     iesys_compute_session_value(esysContext->session_tab[1], NULL, NULL);
-    r = iesys_gen_auths(esysContext, authHandleNode, nvIndexNode, NULL, &auths);
-    return_if_error(r, "Error in computation of auth values");
+    iesys_compute_session_value(esysContext->session_tab[2], NULL, NULL);
 
+    /* Generate the auth values and set them in the SAPI command buffer */
+    r = iesys_gen_auths(esysContext, authHandleNode, nvIndexNode, NULL, &auths);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Error in computation of auth values");
     esysContext->authsCount = auths.count;
     r = Tss2_Sys_SetCmdAuths(esysContext->sys, &auths);
-    if (r != TSS2_RC_SUCCESS) {
-        return r;
-    }
+    return_state_if_error(r, _ESYS_STATE_INIT, "SAPI error on SetCmdAuths");
 
+    /* Trigger execution and finish the async invocation */
     r = Tss2_Sys_ExecuteAsync(esysContext->sys);
-    return_if_error(r, "Finish (Execute Async)");
+    return_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Finish (Execute Async)");
 
     esysContext->state = _ESYS_STATE_SENT;
 
@@ -209,26 +213,34 @@
     ESYS_CONTEXT *esysContext)
 {
     LOG_TRACE("complete");
+    TSS2_RC r;
     if (esysContext == NULL) {
         LOG_ERROR("esyscontext is NULL.");
         return TSS2_ESYS_RC_BAD_REFERENCE;
     }
+
+    /* Check for correct sequence and set sequence to irregular for now */
     if (esysContext->state != _ESYS_STATE_SENT) {
         LOG_ERROR("Esys called in bad sequence.");
         return TSS2_ESYS_RC_BAD_SEQUENCE;
     }
-    TSS2_RC r;
+    esysContext->state = _ESYS_STATE_INTERNALERROR;
+
+    /*Receive the TPM response and handle resubmissions if necessary. */
     r = Tss2_Sys_ExecuteFinish(esysContext->sys, esysContext->timeout);
     if ((r & ~TSS2_RC_LAYER_MASK) == TSS2_BASE_RC_TRY_AGAIN) {
         LOG_DEBUG("A layer below returned TRY_AGAIN: %" PRIx32, r);
+        esysContext->state = _ESYS_STATE_SENT;
         return r;
     }
+    /* This block handle the resubmission of TPM commands given a certain set of
+     * TPM response codes. */
     if (r == TPM2_RC_RETRY || r == TPM2_RC_TESTING || r == TPM2_RC_YIELDED) {
         LOG_DEBUG("TPM returned RETRY, TESTING or YIELDED, which triggers a "
             "resubmission: %" PRIx32, r);
         if (esysContext->submissionCount >= _ESYS_MAX_SUBMISSIONS) {
-            LOG_WARNING("Maximum number of resubmissions has been reached.");
-            esysContext->state = _ESYS_STATE_ERRORRESPONSE;
+            LOG_WARNING("Maximum number of (re)submissions has been reached.");
+            esysContext->state = _ESYS_STATE_INIT;
             return r;
         }
         esysContext->state = _ESYS_STATE_RESUBMISSION;
@@ -239,37 +251,46 @@
                 esysContext->session_type[1],
                 esysContext->session_type[2]);
         if (r != TSS2_RC_SUCCESS) {
-            LOG_ERROR("Error attempting to resubmit");
+            LOG_WARNING("Error attempting to resubmit");
+            /* We do not set esysContext->state here but inherit the most recent
+             * state of the _async function. */
             return r;
         }
         r = TSS2_ESYS_RC_TRY_AGAIN;
+        LOG_DEBUG("Resubmission initiated and returning RC_TRY_AGAIN.");
         return r;
     }
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error finish (ExecuteFinish) NV_UndefineSpace");
+    /* The following is the "regular error" handling. */
+    if (r != TSS2_RC_SUCCESS && (r & TSS2_RC_LAYER_MASK) == 0) {
+        LOG_WARNING("Received TPM Error");
+        esysContext->state = _ESYS_STATE_INIT;
+        return r;
+    } else if (r != TSS2_RC_SUCCESS) {
+        LOG_ERROR("Received a non-TPM Error");
+        esysContext->state = _ESYS_STATE_INTERNALERROR;
         return r;
     }
+
     /*
      * Now the verification of the response (hmac check) and if necessary the
-     * parameter decryption have to be done
+     * parameter decryption have to be done.
      */
     r = iesys_check_response(esysContext);
-    return_if_error(r, "Error: check response");
+    return_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Error: check response");
     /*
      * After the verification of the response we call the complete function
      * to deliver the result.
      */
     r = Tss2_Sys_NV_UndefineSpace_Complete(esysContext->sys);
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error finish (ExecuteFinish) NV_UndefineSpace: %" PRIx32, r);
-        esysContext->state = _ESYS_STATE_ERRORRESPONSE;
-        return r;;
-    }
+    return_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Received error from SAPI"
+                        " unmarshalling" );
     /* The ESYS_TR object (nvIndex) has to be invalidated */
     r = Esys_TR_Close(esysContext, &esysContext->in.NV_UndefineSpace.nvIndex);
     return_if_error(r, "invalidate object");
 
-    esysContext->state = _ESYS_STATE_FINISHED;
+    esysContext->state = _ESYS_STATE_INIT;
+    LOG_DEBUG("context=%p",
+              esysContext);
 
-    return r;
+    return TSS2_RC_SUCCESS;
 }
diff --git a/src/tss2-esys/api/Esys_NV_UndefineSpaceSpecial.c b/src/tss2-esys/api/Esys_NV_UndefineSpaceSpecial.c
index aefd717..241632a 100644
--- a/src/tss2-esys/api/Esys_NV_UndefineSpaceSpecial.c
+++ b/src/tss2-esys/api/Esys_NV_UndefineSpaceSpecial.c
@@ -145,6 +145,7 @@
     RSRC_NODE_T *nvIndexNode;
     RSRC_NODE_T *platformNode;
 
+    /* Check context, sequence correctness and set state to error for now */
     if (esysContext == NULL) {
         LOG_ERROR("esyscontext is NULL.");
         return TSS2_ESYS_RC_BAD_REFERENCE;
@@ -152,41 +153,44 @@
     r = iesys_check_sequence_async(esysContext);
     if (r != TSS2_RC_SUCCESS)
         return r;
-    r = check_session_feasability(shandle1, shandle2, shandle3, 1);
-    return_if_error(r, "Check session usage");
+    esysContext->state = _ESYS_STATE_INTERNALERROR;
 
+    /* Check and store input parameters */
+    r = check_session_feasability(shandle1, shandle2, shandle3, 1);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Check session usage");
     store_input_parameters(esysContext, nvIndex, platform);
+
+    /* Retrieve the metadata objects for provided handles */
     r = esys_GetResourceObject(esysContext, nvIndex, &nvIndexNode);
-    if (r != TPM2_RC_SUCCESS)
-        return r;
+    return_state_if_error(r, _ESYS_STATE_INIT, "nvIndex unknown.");
     r = esys_GetResourceObject(esysContext, platform, &platformNode);
-    if (r != TPM2_RC_SUCCESS)
-        return r;
+    return_state_if_error(r, _ESYS_STATE_INIT, "platform unknown.");
+
+    /* Initial invocation of SAPI to prepare the command buffer with parameters */
     r = Tss2_Sys_NV_UndefineSpaceSpecial_Prepare(esysContext->sys,
                 (nvIndexNode == NULL) ? TPM2_RH_NULL : nvIndexNode->rsrc.handle,
                 (platformNode == NULL) ? TPM2_RH_NULL : platformNode->rsrc.handle);
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error async NV_UndefineSpaceSpecial");
-        return r;
-    }
-    r = init_session_tab(esysContext, shandle1, shandle2, shandle3);
-    return_if_error(r, "Initialize session resources");
+    return_state_if_error(r, _ESYS_STATE_INIT, "SAPI Prepare returned error.");
 
+    /* Calculate the cpHash Values */
+    r = init_session_tab(esysContext, shandle1, shandle2, shandle3);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Initialize session resources");
     iesys_compute_session_value(esysContext->session_tab[0],
                 &nvIndexNode->rsrc.name, &nvIndexNode->auth);
     iesys_compute_session_value(esysContext->session_tab[1],
                 &platformNode->rsrc.name, &platformNode->auth);
-    r = iesys_gen_auths(esysContext, nvIndexNode, platformNode, NULL, &auths);
-    return_if_error(r, "Error in computation of auth values");
+    iesys_compute_session_value(esysContext->session_tab[2], NULL, NULL);
 
+    /* Generate the auth values and set them in the SAPI command buffer */
+    r = iesys_gen_auths(esysContext, nvIndexNode, platformNode, NULL, &auths);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Error in computation of auth values");
     esysContext->authsCount = auths.count;
     r = Tss2_Sys_SetCmdAuths(esysContext->sys, &auths);
-    if (r != TSS2_RC_SUCCESS) {
-        return r;
-    }
+    return_state_if_error(r, _ESYS_STATE_INIT, "SAPI error on SetCmdAuths");
 
+    /* Trigger execution and finish the async invocation */
     r = Tss2_Sys_ExecuteAsync(esysContext->sys);
-    return_if_error(r, "Finish (Execute Async)");
+    return_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Finish (Execute Async)");
 
     esysContext->state = _ESYS_STATE_SENT;
 
@@ -210,26 +214,34 @@
     ESYS_CONTEXT *esysContext)
 {
     LOG_TRACE("complete");
+    TSS2_RC r;
     if (esysContext == NULL) {
         LOG_ERROR("esyscontext is NULL.");
         return TSS2_ESYS_RC_BAD_REFERENCE;
     }
+
+    /* Check for correct sequence and set sequence to irregular for now */
     if (esysContext->state != _ESYS_STATE_SENT) {
         LOG_ERROR("Esys called in bad sequence.");
         return TSS2_ESYS_RC_BAD_SEQUENCE;
     }
-    TSS2_RC r;
+    esysContext->state = _ESYS_STATE_INTERNALERROR;
+
+    /*Receive the TPM response and handle resubmissions if necessary. */
     r = Tss2_Sys_ExecuteFinish(esysContext->sys, esysContext->timeout);
     if ((r & ~TSS2_RC_LAYER_MASK) == TSS2_BASE_RC_TRY_AGAIN) {
         LOG_DEBUG("A layer below returned TRY_AGAIN: %" PRIx32, r);
+        esysContext->state = _ESYS_STATE_SENT;
         return r;
     }
+    /* This block handle the resubmission of TPM commands given a certain set of
+     * TPM response codes. */
     if (r == TPM2_RC_RETRY || r == TPM2_RC_TESTING || r == TPM2_RC_YIELDED) {
         LOG_DEBUG("TPM returned RETRY, TESTING or YIELDED, which triggers a "
             "resubmission: %" PRIx32, r);
         if (esysContext->submissionCount >= _ESYS_MAX_SUBMISSIONS) {
-            LOG_WARNING("Maximum number of resubmissions has been reached.");
-            esysContext->state = _ESYS_STATE_ERRORRESPONSE;
+            LOG_WARNING("Maximum number of (re)submissions has been reached.");
+            esysContext->state = _ESYS_STATE_INIT;
             return r;
         }
         esysContext->state = _ESYS_STATE_RESUBMISSION;
@@ -240,33 +252,42 @@
                 esysContext->session_type[1],
                 esysContext->session_type[2]);
         if (r != TSS2_RC_SUCCESS) {
-            LOG_ERROR("Error attempting to resubmit");
+            LOG_WARNING("Error attempting to resubmit");
+            /* We do not set esysContext->state here but inherit the most recent
+             * state of the _async function. */
             return r;
         }
         r = TSS2_ESYS_RC_TRY_AGAIN;
+        LOG_DEBUG("Resubmission initiated and returning RC_TRY_AGAIN.");
         return r;
     }
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error finish (ExecuteFinish) NV_UndefineSpaceSpecial");
+    /* The following is the "regular error" handling. */
+    if (r != TSS2_RC_SUCCESS && (r & TSS2_RC_LAYER_MASK) == 0) {
+        LOG_WARNING("Received TPM Error");
+        esysContext->state = _ESYS_STATE_INIT;
+        return r;
+    } else if (r != TSS2_RC_SUCCESS) {
+        LOG_ERROR("Received a non-TPM Error");
+        esysContext->state = _ESYS_STATE_INTERNALERROR;
         return r;
     }
+
     /*
      * Now the verification of the response (hmac check) and if necessary the
-     * parameter decryption have to be done
+     * parameter decryption have to be done.
      */
     r = iesys_check_response(esysContext);
-    return_if_error(r, "Error: check response");
+    return_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Error: check response");
     /*
      * After the verification of the response we call the complete function
      * to deliver the result.
      */
     r = Tss2_Sys_NV_UndefineSpaceSpecial_Complete(esysContext->sys);
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error finish (ExecuteFinish) NV_UndefineSpaceSpecial: %" PRIx32, r);
-        esysContext->state = _ESYS_STATE_ERRORRESPONSE;
-        return r;;
-    }
-    esysContext->state = _ESYS_STATE_FINISHED;
+    return_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Received error from SAPI"
+                        " unmarshalling" );
+    esysContext->state = _ESYS_STATE_INIT;
+    LOG_DEBUG("context=%p",
+              esysContext);
 
-    return r;
+    return TSS2_RC_SUCCESS;
 }
diff --git a/src/tss2-esys/api/Esys_NV_Write.c b/src/tss2-esys/api/Esys_NV_Write.c
index 54ead1c..b2e8e99 100644
--- a/src/tss2-esys/api/Esys_NV_Write.c
+++ b/src/tss2-esys/api/Esys_NV_Write.c
@@ -165,6 +165,7 @@
     RSRC_NODE_T *authHandleNode;
     RSRC_NODE_T *nvIndexNode;
 
+    /* Check context, sequence correctness and set state to error for now */
     if (esysContext == NULL) {
         LOG_ERROR("esyscontext is NULL.");
         return TSS2_ESYS_RC_BAD_REFERENCE;
@@ -172,45 +173,47 @@
     r = iesys_check_sequence_async(esysContext);
     if (r != TSS2_RC_SUCCESS)
         return r;
-    r = check_session_feasability(shandle1, shandle2, shandle3, 1);
-    return_if_error(r, "Check session usage");
+    esysContext->state = _ESYS_STATE_INTERNALERROR;
 
+    /* Check and store input parameters */
+    r = check_session_feasability(shandle1, shandle2, shandle3, 1);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Check session usage");
     store_input_parameters(esysContext, authHandle, nvIndex,
                 data,
                 offset);
+
+    /* Retrieve the metadata objects for provided handles */
     r = esys_GetResourceObject(esysContext, authHandle, &authHandleNode);
-    if (r != TPM2_RC_SUCCESS)
-        return r;
+    return_state_if_error(r, _ESYS_STATE_INIT, "authHandle unknown.");
     r = esys_GetResourceObject(esysContext, nvIndex, &nvIndexNode);
-    if (r != TPM2_RC_SUCCESS)
-        return r;
+    return_state_if_error(r, _ESYS_STATE_INIT, "nvIndex unknown.");
+
+    /* Initial invocation of SAPI to prepare the command buffer with parameters */
     r = Tss2_Sys_NV_Write_Prepare(esysContext->sys,
                 (authHandleNode == NULL) ? TPM2_RH_NULL : authHandleNode->rsrc.handle,
                 (nvIndexNode == NULL) ? TPM2_RH_NULL : nvIndexNode->rsrc.handle,
                 data,
                 offset);
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error async NV_Write");
-        return r;
-    }
-    r = init_session_tab(esysContext, shandle1, shandle2, shandle3);
-    return_if_error(r, "Initialize session resources");
+    return_state_if_error(r, _ESYS_STATE_INIT, "SAPI Prepare returned error.");
 
+    /* Calculate the cpHash Values */
+    r = init_session_tab(esysContext, shandle1, shandle2, shandle3);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Initialize session resources");
     iesys_compute_session_value(esysContext->session_tab[0],
                 &authHandleNode->rsrc.name, &authHandleNode->auth);
     iesys_compute_session_value(esysContext->session_tab[1], NULL, NULL);
     iesys_compute_session_value(esysContext->session_tab[2], NULL, NULL);
-    r = iesys_gen_auths(esysContext, authHandleNode, nvIndexNode, NULL, &auths);
-    return_if_error(r, "Error in computation of auth values");
 
+    /* Generate the auth values and set them in the SAPI command buffer */
+    r = iesys_gen_auths(esysContext, authHandleNode, nvIndexNode, NULL, &auths);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Error in computation of auth values");
     esysContext->authsCount = auths.count;
     r = Tss2_Sys_SetCmdAuths(esysContext->sys, &auths);
-    if (r != TSS2_RC_SUCCESS) {
-        return r;
-    }
+    return_state_if_error(r, _ESYS_STATE_INIT, "SAPI error on SetCmdAuths");
 
+    /* Trigger execution and finish the async invocation */
     r = Tss2_Sys_ExecuteAsync(esysContext->sys);
-    return_if_error(r, "Finish (Execute Async)");
+    return_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Finish (Execute Async)");
 
     esysContext->state = _ESYS_STATE_SENT;
 
@@ -234,26 +237,34 @@
     ESYS_CONTEXT *esysContext)
 {
     LOG_TRACE("complete");
+    TSS2_RC r;
     if (esysContext == NULL) {
         LOG_ERROR("esyscontext is NULL.");
         return TSS2_ESYS_RC_BAD_REFERENCE;
     }
+
+    /* Check for correct sequence and set sequence to irregular for now */
     if (esysContext->state != _ESYS_STATE_SENT) {
         LOG_ERROR("Esys called in bad sequence.");
         return TSS2_ESYS_RC_BAD_SEQUENCE;
     }
-    TSS2_RC r;
+    esysContext->state = _ESYS_STATE_INTERNALERROR;
+
+    /*Receive the TPM response and handle resubmissions if necessary. */
     r = Tss2_Sys_ExecuteFinish(esysContext->sys, esysContext->timeout);
     if ((r & ~TSS2_RC_LAYER_MASK) == TSS2_BASE_RC_TRY_AGAIN) {
         LOG_DEBUG("A layer below returned TRY_AGAIN: %" PRIx32, r);
+        esysContext->state = _ESYS_STATE_SENT;
         return r;
     }
+    /* This block handle the resubmission of TPM commands given a certain set of
+     * TPM response codes. */
     if (r == TPM2_RC_RETRY || r == TPM2_RC_TESTING || r == TPM2_RC_YIELDED) {
         LOG_DEBUG("TPM returned RETRY, TESTING or YIELDED, which triggers a "
             "resubmission: %" PRIx32, r);
         if (esysContext->submissionCount >= _ESYS_MAX_SUBMISSIONS) {
-            LOG_WARNING("Maximum number of resubmissions has been reached.");
-            esysContext->state = _ESYS_STATE_ERRORRESPONSE;
+            LOG_WARNING("Maximum number of (re)submissions has been reached.");
+            esysContext->state = _ESYS_STATE_INIT;
             return r;
         }
         esysContext->state = _ESYS_STATE_RESUBMISSION;
@@ -266,45 +277,55 @@
                 esysContext->in.NV_Write.data,
                 esysContext->in.NV_Write.offset);
         if (r != TSS2_RC_SUCCESS) {
-            LOG_ERROR("Error attempting to resubmit");
+            LOG_WARNING("Error attempting to resubmit");
+            /* We do not set esysContext->state here but inherit the most recent
+             * state of the _async function. */
             return r;
         }
         r = TSS2_ESYS_RC_TRY_AGAIN;
+        LOG_DEBUG("Resubmission initiated and returning RC_TRY_AGAIN.");
         return r;
     }
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error finish (ExecuteFinish) NV_Write");
+    /* The following is the "regular error" handling. */
+    if (r != TSS2_RC_SUCCESS && (r & TSS2_RC_LAYER_MASK) == 0) {
+        LOG_WARNING("Received TPM Error");
+        esysContext->state = _ESYS_STATE_INIT;
+        return r;
+    } else if (r != TSS2_RC_SUCCESS) {
+        LOG_ERROR("Received a non-TPM Error");
+        esysContext->state = _ESYS_STATE_INTERNALERROR;
         return r;
     }
+
     /*
      * Now the verification of the response (hmac check) and if necessary the
-     * parameter decryption have to be done
+     * parameter decryption have to be done.
      */
     r = iesys_check_response(esysContext);
-    return_if_error(r, "Error: check response");
+    return_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Error: check response");
     /*
      * After the verification of the response we call the complete function
      * to deliver the result.
      */
     r = Tss2_Sys_NV_Write_Complete(esysContext->sys);
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error finish (ExecuteFinish) NV_Write: %" PRIx32, r);
-        esysContext->state = _ESYS_STATE_ERRORRESPONSE;
-        return r;;
-    }
+    return_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Received error from SAPI"
+                        " unmarshalling" );
 
     ESYS_TR nvIndex = esysContext->in.NV_Write.nvIndex;
-        RSRC_NODE_T *nvIndexNode;
+    RSRC_NODE_T *nvIndexNode;
     r = esys_GetResourceObject(esysContext, nvIndex, &nvIndexNode);
     return_if_error(r, "get resource");
 
+    /* Update name in meta data because of possibly changed attributes */
     if (nvIndexNode != NULL) {
         nvIndexNode->rsrc.misc.rsrc_nv_pub.nvPublic.attributes |= TPMA_NV_WRITTEN;
         r = iesys_nv_get_name(&nvIndexNode->rsrc.misc.rsrc_nv_pub,
                               &nvIndexNode->rsrc.name);
         return_if_error(r, "Error get nvname")
      }
-    esysContext->state = _ESYS_STATE_FINISHED;
+    esysContext->state = _ESYS_STATE_INIT;
+    LOG_DEBUG("context=%p",
+              esysContext);
 
-    return r;
+    return TSS2_RC_SUCCESS;
 }
diff --git a/src/tss2-esys/api/Esys_NV_WriteLock.c b/src/tss2-esys/api/Esys_NV_WriteLock.c
index 8fea452..5420a6b 100644
--- a/src/tss2-esys/api/Esys_NV_WriteLock.c
+++ b/src/tss2-esys/api/Esys_NV_WriteLock.c
@@ -145,6 +145,7 @@
     RSRC_NODE_T *authHandleNode;
     RSRC_NODE_T *nvIndexNode;
 
+    /* Check context, sequence correctness and set state to error for now */
     if (esysContext == NULL) {
         LOG_ERROR("esyscontext is NULL.");
         return TSS2_ESYS_RC_BAD_REFERENCE;
@@ -152,40 +153,43 @@
     r = iesys_check_sequence_async(esysContext);
     if (r != TSS2_RC_SUCCESS)
         return r;
-    r = check_session_feasability(shandle1, shandle2, shandle3, 1);
-    return_if_error(r, "Check session usage");
+    esysContext->state = _ESYS_STATE_INTERNALERROR;
 
+    /* Check and store input parameters */
+    r = check_session_feasability(shandle1, shandle2, shandle3, 1);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Check session usage");
     store_input_parameters(esysContext, authHandle, nvIndex);
+
+    /* Retrieve the metadata objects for provided handles */
     r = esys_GetResourceObject(esysContext, authHandle, &authHandleNode);
-    if (r != TPM2_RC_SUCCESS)
-        return r;
+    return_state_if_error(r, _ESYS_STATE_INIT, "authHandle unknown.");
     r = esys_GetResourceObject(esysContext, nvIndex, &nvIndexNode);
-    if (r != TPM2_RC_SUCCESS)
-        return r;
+    return_state_if_error(r, _ESYS_STATE_INIT, "nvIndex unknown.");
+
+    /* Initial invocation of SAPI to prepare the command buffer with parameters */
     r = Tss2_Sys_NV_WriteLock_Prepare(esysContext->sys,
                 (authHandleNode == NULL) ? TPM2_RH_NULL : authHandleNode->rsrc.handle,
                 (nvIndexNode == NULL) ? TPM2_RH_NULL : nvIndexNode->rsrc.handle);
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error async NV_WriteLock");
-        return r;
-    }
-    r = init_session_tab(esysContext, shandle1, shandle2, shandle3);
-    return_if_error(r, "Initialize session resources");
+    return_state_if_error(r, _ESYS_STATE_INIT, "SAPI Prepare returned error.");
 
+    /* Calculate the cpHash Values */
+    r = init_session_tab(esysContext, shandle1, shandle2, shandle3);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Initialize session resources");
     iesys_compute_session_value(esysContext->session_tab[0],
                 &authHandleNode->rsrc.name, &authHandleNode->auth);
     iesys_compute_session_value(esysContext->session_tab[1], NULL, NULL);
-    r = iesys_gen_auths(esysContext, authHandleNode, nvIndexNode, NULL, &auths);
-    return_if_error(r, "Error in computation of auth values");
+    iesys_compute_session_value(esysContext->session_tab[2], NULL, NULL);
 
+    /* Generate the auth values and set them in the SAPI command buffer */
+    r = iesys_gen_auths(esysContext, authHandleNode, nvIndexNode, NULL, &auths);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Error in computation of auth values");
     esysContext->authsCount = auths.count;
     r = Tss2_Sys_SetCmdAuths(esysContext->sys, &auths);
-    if (r != TSS2_RC_SUCCESS) {
-        return r;
-    }
+    return_state_if_error(r, _ESYS_STATE_INIT, "SAPI error on SetCmdAuths");
 
+    /* Trigger execution and finish the async invocation */
     r = Tss2_Sys_ExecuteAsync(esysContext->sys);
-    return_if_error(r, "Finish (Execute Async)");
+    return_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Finish (Execute Async)");
 
     esysContext->state = _ESYS_STATE_SENT;
 
@@ -209,26 +213,34 @@
     ESYS_CONTEXT *esysContext)
 {
     LOG_TRACE("complete");
+    TSS2_RC r;
     if (esysContext == NULL) {
         LOG_ERROR("esyscontext is NULL.");
         return TSS2_ESYS_RC_BAD_REFERENCE;
     }
+
+    /* Check for correct sequence and set sequence to irregular for now */
     if (esysContext->state != _ESYS_STATE_SENT) {
         LOG_ERROR("Esys called in bad sequence.");
         return TSS2_ESYS_RC_BAD_SEQUENCE;
     }
-    TSS2_RC r;
+    esysContext->state = _ESYS_STATE_INTERNALERROR;
+
+    /*Receive the TPM response and handle resubmissions if necessary. */
     r = Tss2_Sys_ExecuteFinish(esysContext->sys, esysContext->timeout);
     if ((r & ~TSS2_RC_LAYER_MASK) == TSS2_BASE_RC_TRY_AGAIN) {
         LOG_DEBUG("A layer below returned TRY_AGAIN: %" PRIx32, r);
+        esysContext->state = _ESYS_STATE_SENT;
         return r;
     }
+    /* This block handle the resubmission of TPM commands given a certain set of
+     * TPM response codes. */
     if (r == TPM2_RC_RETRY || r == TPM2_RC_TESTING || r == TPM2_RC_YIELDED) {
         LOG_DEBUG("TPM returned RETRY, TESTING or YIELDED, which triggers a "
             "resubmission: %" PRIx32, r);
         if (esysContext->submissionCount >= _ESYS_MAX_SUBMISSIONS) {
-            LOG_WARNING("Maximum number of resubmissions has been reached.");
-            esysContext->state = _ESYS_STATE_ERRORRESPONSE;
+            LOG_WARNING("Maximum number of (re)submissions has been reached.");
+            esysContext->state = _ESYS_STATE_INIT;
             return r;
         }
         esysContext->state = _ESYS_STATE_RESUBMISSION;
@@ -239,45 +251,55 @@
                 esysContext->session_type[1],
                 esysContext->session_type[2]);
         if (r != TSS2_RC_SUCCESS) {
-            LOG_ERROR("Error attempting to resubmit");
+            LOG_WARNING("Error attempting to resubmit");
+            /* We do not set esysContext->state here but inherit the most recent
+             * state of the _async function. */
             return r;
         }
         r = TSS2_ESYS_RC_TRY_AGAIN;
+        LOG_DEBUG("Resubmission initiated and returning RC_TRY_AGAIN.");
         return r;
     }
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error finish (ExecuteFinish) NV_WriteLock");
+    /* The following is the "regular error" handling. */
+    if (r != TSS2_RC_SUCCESS && (r & TSS2_RC_LAYER_MASK) == 0) {
+        LOG_WARNING("Received TPM Error");
+        esysContext->state = _ESYS_STATE_INIT;
+        return r;
+    } else if (r != TSS2_RC_SUCCESS) {
+        LOG_ERROR("Received a non-TPM Error");
+        esysContext->state = _ESYS_STATE_INTERNALERROR;
         return r;
     }
+
     /*
      * Now the verification of the response (hmac check) and if necessary the
-     * parameter decryption have to be done
+     * parameter decryption have to be done.
      */
     r = iesys_check_response(esysContext);
-    return_if_error(r, "Error: check response");
+    return_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Error: check response");
     /*
      * After the verification of the response we call the complete function
      * to deliver the result.
      */
     r = Tss2_Sys_NV_WriteLock_Complete(esysContext->sys);
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error finish (ExecuteFinish) NV_WriteLock: %" PRIx32, r);
-        esysContext->state = _ESYS_STATE_ERRORRESPONSE;
-        return r;;
-    }
+    return_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Received error from SAPI"
+                        " unmarshalling" );
 
     ESYS_TR nvIndex = esysContext->in.NV_Write.nvIndex;
-    RSRC_NODE_T *nvIndexNode;
+        RSRC_NODE_T *nvIndexNode;
     r = esys_GetResourceObject(esysContext, nvIndex, &nvIndexNode);
     return_if_error(r, "get resource");
 
+    /* Update name in meta data because of possibly changed attributes */
     if (nvIndexNode != NULL) {
         nvIndexNode->rsrc.misc.rsrc_nv_pub.nvPublic.attributes |=  TPMA_NV_WRITELOCKED;
         r = iesys_nv_get_name(&nvIndexNode->rsrc.misc.rsrc_nv_pub,
                               &nvIndexNode->rsrc.name);
         return_if_error(r, "Error get nvname")
      }
-    esysContext->state = _ESYS_STATE_FINISHED;
+    esysContext->state = _ESYS_STATE_INIT;
+    LOG_DEBUG("context=%p",
+              esysContext);
 
-    return r;
+    return TSS2_RC_SUCCESS;
 }
diff --git a/src/tss2-esys/api/Esys_ObjectChangeAuth.c b/src/tss2-esys/api/Esys_ObjectChangeAuth.c
index 0ab61fc..4927130 100644
--- a/src/tss2-esys/api/Esys_ObjectChangeAuth.c
+++ b/src/tss2-esys/api/Esys_ObjectChangeAuth.c
@@ -162,6 +162,7 @@
     RSRC_NODE_T *objectHandleNode;
     RSRC_NODE_T *parentHandleNode;
 
+    /* Check context, sequence correctness and set state to error for now */
     if (esysContext == NULL) {
         LOG_ERROR("esyscontext is NULL.");
         return TSS2_ESYS_RC_BAD_REFERENCE;
@@ -169,43 +170,45 @@
     r = iesys_check_sequence_async(esysContext);
     if (r != TSS2_RC_SUCCESS)
         return r;
-    r = check_session_feasability(shandle1, shandle2, shandle3, 1);
-    return_if_error(r, "Check session usage");
+    esysContext->state = _ESYS_STATE_INTERNALERROR;
 
+    /* Check and store input parameters */
+    r = check_session_feasability(shandle1, shandle2, shandle3, 1);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Check session usage");
     store_input_parameters(esysContext, objectHandle, parentHandle,
                 newAuth);
+
+    /* Retrieve the metadata objects for provided handles */
     r = esys_GetResourceObject(esysContext, objectHandle, &objectHandleNode);
-    if (r != TPM2_RC_SUCCESS)
-        return r;
+    return_state_if_error(r, _ESYS_STATE_INIT, "objectHandle unknown.");
     r = esys_GetResourceObject(esysContext, parentHandle, &parentHandleNode);
-    if (r != TPM2_RC_SUCCESS)
-        return r;
+    return_state_if_error(r, _ESYS_STATE_INIT, "parentHandle unknown.");
+
+    /* Initial invocation of SAPI to prepare the command buffer with parameters */
     r = Tss2_Sys_ObjectChangeAuth_Prepare(esysContext->sys,
                 (objectHandleNode == NULL) ? TPM2_RH_NULL : objectHandleNode->rsrc.handle,
                 (parentHandleNode == NULL) ? TPM2_RH_NULL : parentHandleNode->rsrc.handle,
                 newAuth);
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error async ObjectChangeAuth");
-        return r;
-    }
-    r = init_session_tab(esysContext, shandle1, shandle2, shandle3);
-    return_if_error(r, "Initialize session resources");
+    return_state_if_error(r, _ESYS_STATE_INIT, "SAPI Prepare returned error.");
 
+    /* Calculate the cpHash Values */
+    r = init_session_tab(esysContext, shandle1, shandle2, shandle3);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Initialize session resources");
     iesys_compute_session_value(esysContext->session_tab[0],
                 &objectHandleNode->rsrc.name, &objectHandleNode->auth);
     iesys_compute_session_value(esysContext->session_tab[1], NULL, NULL);
     iesys_compute_session_value(esysContext->session_tab[2], NULL, NULL);
-    r = iesys_gen_auths(esysContext, objectHandleNode, parentHandleNode, NULL, &auths);
-    return_if_error(r, "Error in computation of auth values");
 
+    /* Generate the auth values and set them in the SAPI command buffer */
+    r = iesys_gen_auths(esysContext, objectHandleNode, parentHandleNode, NULL, &auths);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Error in computation of auth values");
     esysContext->authsCount = auths.count;
     r = Tss2_Sys_SetCmdAuths(esysContext->sys, &auths);
-    if (r != TSS2_RC_SUCCESS) {
-        return r;
-    }
+    return_state_if_error(r, _ESYS_STATE_INIT, "SAPI error on SetCmdAuths");
 
+    /* Trigger execution and finish the async invocation */
     r = Tss2_Sys_ExecuteAsync(esysContext->sys);
-    return_if_error(r, "Finish (Execute Async)");
+    return_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Finish (Execute Async)");
 
     esysContext->state = _ESYS_STATE_SENT;
 
@@ -232,32 +235,42 @@
     TPM2B_PRIVATE **outPrivate)
 {
     LOG_TRACE("complete");
+    TSS2_RC r;
     if (esysContext == NULL) {
         LOG_ERROR("esyscontext is NULL.");
         return TSS2_ESYS_RC_BAD_REFERENCE;
     }
+
+    /* Check for correct sequence and set sequence to irregular for now */
     if (esysContext->state != _ESYS_STATE_SENT) {
         LOG_ERROR("Esys called in bad sequence.");
         return TSS2_ESYS_RC_BAD_SEQUENCE;
     }
-    TSS2_RC r;
+    esysContext->state = _ESYS_STATE_INTERNALERROR;
+
+    /* Allocate memory for response parameters */
     if (outPrivate != NULL) {
         *outPrivate = calloc(sizeof(TPM2B_PRIVATE), 1);
         if (*outPrivate == NULL) {
             return_error(TSS2_ESYS_RC_MEMORY, "Out of memory");
         }
     }
+
+    /*Receive the TPM response and handle resubmissions if necessary. */
     r = Tss2_Sys_ExecuteFinish(esysContext->sys, esysContext->timeout);
     if ((r & ~TSS2_RC_LAYER_MASK) == TSS2_BASE_RC_TRY_AGAIN) {
         LOG_DEBUG("A layer below returned TRY_AGAIN: %" PRIx32, r);
+        esysContext->state = _ESYS_STATE_SENT;
         goto error_cleanup;
     }
+    /* This block handle the resubmission of TPM commands given a certain set of
+     * TPM response codes. */
     if (r == TPM2_RC_RETRY || r == TPM2_RC_TESTING || r == TPM2_RC_YIELDED) {
         LOG_DEBUG("TPM returned RETRY, TESTING or YIELDED, which triggers a "
             "resubmission: %" PRIx32, r);
         if (esysContext->submissionCount >= _ESYS_MAX_SUBMISSIONS) {
-            LOG_WARNING("Maximum number of resubmissions has been reached.");
-            esysContext->state = _ESYS_STATE_ERRORRESPONSE;
+            LOG_WARNING("Maximum number of (re)submissions has been reached.");
+            esysContext->state = _ESYS_STATE_INIT;
             goto error_cleanup;
         }
         esysContext->state = _ESYS_STATE_RESUBMISSION;
@@ -269,22 +282,32 @@
                 esysContext->session_type[2],
                 esysContext->in.ObjectChangeAuth.newAuth);
         if (r != TSS2_RC_SUCCESS) {
-            LOG_ERROR("Error attempting to resubmit");
+            LOG_WARNING("Error attempting to resubmit");
+            /* We do not set esysContext->state here but inherit the most recent
+             * state of the _async function. */
             goto error_cleanup;
         }
         r = TSS2_ESYS_RC_TRY_AGAIN;
+        LOG_DEBUG("Resubmission initiated and returning RC_TRY_AGAIN.");
         goto error_cleanup;
     }
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error finish (ExecuteFinish) ObjectChangeAuth");
+    /* The following is the "regular error" handling. */
+    if (r != TSS2_RC_SUCCESS && (r & TSS2_RC_LAYER_MASK) == 0) {
+        LOG_WARNING("Received TPM Error");
+        esysContext->state = _ESYS_STATE_INIT;
+        goto error_cleanup;
+    } else if (r != TSS2_RC_SUCCESS) {
+        LOG_ERROR("Received a non-TPM Error");
+        esysContext->state = _ESYS_STATE_INTERNALERROR;
         goto error_cleanup;
     }
+
     /*
      * Now the verification of the response (hmac check) and if necessary the
-     * parameter decryption have to be done
+     * parameter decryption have to be done.
      */
     r = iesys_check_response(esysContext);
-    goto_if_error(r, "Error: check response",
+    goto_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Error: check response",
                       error_cleanup);
     /*
      * After the verification of the response we call the complete function
@@ -292,17 +315,17 @@
      */
     r = Tss2_Sys_ObjectChangeAuth_Complete(esysContext->sys,
                 (outPrivate != NULL) ? *outPrivate : NULL);
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error finish (ExecuteFinish) ObjectChangeAuth: %" PRIx32, r);
-        esysContext->state = _ESYS_STATE_ERRORRESPONSE;
-        goto error_cleanup;;
-    }
-    esysContext->state = _ESYS_STATE_FINISHED;
+    goto_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Received error from SAPI"
+                        " unmarshalling" ,error_cleanup);
+    esysContext->state = _ESYS_STATE_INIT;
+    LOG_DEBUG("context=%p, outPrivate=%p",
+              esysContext, outPrivate);
 
-    return r;
+    return TSS2_RC_SUCCESS;
 
 error_cleanup:
     if (outPrivate != NULL)
         SAFE_FREE(*outPrivate);
+
     return r;
 }
diff --git a/src/tss2-esys/api/Esys_PCR_Allocate.c b/src/tss2-esys/api/Esys_PCR_Allocate.c
index d40ff60..19147e0 100644
--- a/src/tss2-esys/api/Esys_PCR_Allocate.c
+++ b/src/tss2-esys/api/Esys_PCR_Allocate.c
@@ -164,6 +164,7 @@
     TSS2L_SYS_AUTH_COMMAND auths;
     RSRC_NODE_T *authHandleNode;
 
+    /* Check context, sequence correctness and set state to error for now */
     if (esysContext == NULL) {
         LOG_ERROR("esyscontext is NULL.");
         return TSS2_ESYS_RC_BAD_REFERENCE;
@@ -171,38 +172,42 @@
     r = iesys_check_sequence_async(esysContext);
     if (r != TSS2_RC_SUCCESS)
         return r;
-    r = check_session_feasability(shandle1, shandle2, shandle3, 1);
-    return_if_error(r, "Check session usage");
+    esysContext->state = _ESYS_STATE_INTERNALERROR;
 
+    /* Check and store input parameters */
+    r = check_session_feasability(shandle1, shandle2, shandle3, 1);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Check session usage");
     store_input_parameters(esysContext, authHandle,
                 pcrAllocation);
+
+    /* Retrieve the metadata objects for provided handles */
     r = esys_GetResourceObject(esysContext, authHandle, &authHandleNode);
-    if (r != TPM2_RC_SUCCESS)
-        return r;
+    return_state_if_error(r, _ESYS_STATE_INIT, "authHandle unknown.");
+
+    /* Initial invocation of SAPI to prepare the command buffer with parameters */
     r = Tss2_Sys_PCR_Allocate_Prepare(esysContext->sys,
                 (authHandleNode == NULL) ? TPM2_RH_NULL : authHandleNode->rsrc.handle,
                 pcrAllocation);
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error async PCR_Allocate");
-        return r;
-    }
-    r = init_session_tab(esysContext, shandle1, shandle2, shandle3);
-    return_if_error(r, "Initialize session resources");
+    return_state_if_error(r, _ESYS_STATE_INIT, "SAPI Prepare returned error.");
 
+    /* Calculate the cpHash Values */
+    r = init_session_tab(esysContext, shandle1, shandle2, shandle3);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Initialize session resources");
     iesys_compute_session_value(esysContext->session_tab[0],
                 &authHandleNode->rsrc.name, &authHandleNode->auth);
     iesys_compute_session_value(esysContext->session_tab[1], NULL, NULL);
-    r = iesys_gen_auths(esysContext, authHandleNode, NULL, NULL, &auths);
-    return_if_error(r, "Error in computation of auth values");
+    iesys_compute_session_value(esysContext->session_tab[2], NULL, NULL);
 
+    /* Generate the auth values and set them in the SAPI command buffer */
+    r = iesys_gen_auths(esysContext, authHandleNode, NULL, NULL, &auths);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Error in computation of auth values");
     esysContext->authsCount = auths.count;
     r = Tss2_Sys_SetCmdAuths(esysContext->sys, &auths);
-    if (r != TSS2_RC_SUCCESS) {
-        return r;
-    }
+    return_state_if_error(r, _ESYS_STATE_INIT, "SAPI error on SetCmdAuths");
 
+    /* Trigger execution and finish the async invocation */
     r = Tss2_Sys_ExecuteAsync(esysContext->sys);
-    return_if_error(r, "Finish (Execute Async)");
+    return_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Finish (Execute Async)");
 
     esysContext->state = _ESYS_STATE_SENT;
 
@@ -238,26 +243,34 @@
     UINT32 *sizeAvailable)
 {
     LOG_TRACE("complete");
+    TSS2_RC r;
     if (esysContext == NULL) {
         LOG_ERROR("esyscontext is NULL.");
         return TSS2_ESYS_RC_BAD_REFERENCE;
     }
+
+    /* Check for correct sequence and set sequence to irregular for now */
     if (esysContext->state != _ESYS_STATE_SENT) {
         LOG_ERROR("Esys called in bad sequence.");
         return TSS2_ESYS_RC_BAD_SEQUENCE;
     }
-    TSS2_RC r;
+    esysContext->state = _ESYS_STATE_INTERNALERROR;
+
+    /*Receive the TPM response and handle resubmissions if necessary. */
     r = Tss2_Sys_ExecuteFinish(esysContext->sys, esysContext->timeout);
     if ((r & ~TSS2_RC_LAYER_MASK) == TSS2_BASE_RC_TRY_AGAIN) {
         LOG_DEBUG("A layer below returned TRY_AGAIN: %" PRIx32, r);
+        esysContext->state = _ESYS_STATE_SENT;
         return r;
     }
+    /* This block handle the resubmission of TPM commands given a certain set of
+     * TPM response codes. */
     if (r == TPM2_RC_RETRY || r == TPM2_RC_TESTING || r == TPM2_RC_YIELDED) {
         LOG_DEBUG("TPM returned RETRY, TESTING or YIELDED, which triggers a "
             "resubmission: %" PRIx32, r);
         if (esysContext->submissionCount >= _ESYS_MAX_SUBMISSIONS) {
-            LOG_WARNING("Maximum number of resubmissions has been reached.");
-            esysContext->state = _ESYS_STATE_ERRORRESPONSE;
+            LOG_WARNING("Maximum number of (re)submissions has been reached.");
+            esysContext->state = _ESYS_STATE_INIT;
             return r;
         }
         esysContext->state = _ESYS_STATE_RESUBMISSION;
@@ -268,22 +281,32 @@
                 esysContext->session_type[2],
                 esysContext->in.PCR_Allocate.pcrAllocation);
         if (r != TSS2_RC_SUCCESS) {
-            LOG_ERROR("Error attempting to resubmit");
+            LOG_WARNING("Error attempting to resubmit");
+            /* We do not set esysContext->state here but inherit the most recent
+             * state of the _async function. */
             return r;
         }
         r = TSS2_ESYS_RC_TRY_AGAIN;
+        LOG_DEBUG("Resubmission initiated and returning RC_TRY_AGAIN.");
         return r;
     }
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error finish (ExecuteFinish) PCR_Allocate");
+    /* The following is the "regular error" handling. */
+    if (r != TSS2_RC_SUCCESS && (r & TSS2_RC_LAYER_MASK) == 0) {
+        LOG_WARNING("Received TPM Error");
+        esysContext->state = _ESYS_STATE_INIT;
+        return r;
+    } else if (r != TSS2_RC_SUCCESS) {
+        LOG_ERROR("Received a non-TPM Error");
+        esysContext->state = _ESYS_STATE_INTERNALERROR;
         return r;
     }
+
     /*
      * Now the verification of the response (hmac check) and if necessary the
-     * parameter decryption have to be done
+     * parameter decryption have to be done.
      */
     r = iesys_check_response(esysContext);
-    return_if_error(r, "Error: check response");
+    return_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Error: check response");
     /*
      * After the verification of the response we call the complete function
      * to deliver the result.
@@ -293,12 +316,13 @@
                 maxPCR,
                 sizeNeeded,
                 sizeAvailable);
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error finish (ExecuteFinish) PCR_Allocate: %" PRIx32, r);
-        esysContext->state = _ESYS_STATE_ERRORRESPONSE;
-        return r;;
-    }
-    esysContext->state = _ESYS_STATE_FINISHED;
+    return_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Received error from SAPI"
+                        " unmarshalling" );
+    esysContext->state = _ESYS_STATE_INIT;
+    LOG_DEBUG("context=%p, allocationSuccess=%p, maxPCR=%p,"
+              "sizeNeeded=%p, sizeAvailable=%p",
+              esysContext, allocationSuccess, maxPCR,
+              sizeNeeded, sizeAvailable);
 
-    return r;
+    return TSS2_RC_SUCCESS;
 }
diff --git a/src/tss2-esys/api/Esys_PCR_Event.c b/src/tss2-esys/api/Esys_PCR_Event.c
index 87f4064..8398301 100644
--- a/src/tss2-esys/api/Esys_PCR_Event.c
+++ b/src/tss2-esys/api/Esys_PCR_Event.c
@@ -152,6 +152,7 @@
     TSS2L_SYS_AUTH_COMMAND auths;
     RSRC_NODE_T *pcrHandleNode;
 
+    /* Check context, sequence correctness and set state to error for now */
     if (esysContext == NULL) {
         LOG_ERROR("esyscontext is NULL.");
         return TSS2_ESYS_RC_BAD_REFERENCE;
@@ -159,38 +160,42 @@
     r = iesys_check_sequence_async(esysContext);
     if (r != TSS2_RC_SUCCESS)
         return r;
-    r = check_session_feasability(shandle1, shandle2, shandle3, 1);
-    return_if_error(r, "Check session usage");
+    esysContext->state = _ESYS_STATE_INTERNALERROR;
 
+    /* Check and store input parameters */
+    r = check_session_feasability(shandle1, shandle2, shandle3, 1);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Check session usage");
     store_input_parameters(esysContext, pcrHandle,
                 eventData);
+
+    /* Retrieve the metadata objects for provided handles */
     r = esys_GetResourceObject(esysContext, pcrHandle, &pcrHandleNode);
-    if (r != TPM2_RC_SUCCESS)
-        return r;
+    return_state_if_error(r, _ESYS_STATE_INIT, "pcrHandle unknown.");
+
+    /* Initial invocation of SAPI to prepare the command buffer with parameters */
     r = Tss2_Sys_PCR_Event_Prepare(esysContext->sys,
                 (pcrHandleNode == NULL) ? TPM2_RH_NULL : pcrHandleNode->rsrc.handle,
                 eventData);
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error async PCR_Event");
-        return r;
-    }
-    r = init_session_tab(esysContext, shandle1, shandle2, shandle3);
-    return_if_error(r, "Initialize session resources");
+    return_state_if_error(r, _ESYS_STATE_INIT, "SAPI Prepare returned error.");
 
+    /* Calculate the cpHash Values */
+    r = init_session_tab(esysContext, shandle1, shandle2, shandle3);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Initialize session resources");
     iesys_compute_session_value(esysContext->session_tab[0],
                 &pcrHandleNode->rsrc.name, &pcrHandleNode->auth);
     iesys_compute_session_value(esysContext->session_tab[1], NULL, NULL);
-    r = iesys_gen_auths(esysContext, pcrHandleNode, NULL, NULL, &auths);
-    return_if_error(r, "Error in computation of auth values");
+    iesys_compute_session_value(esysContext->session_tab[2], NULL, NULL);
 
+    /* Generate the auth values and set them in the SAPI command buffer */
+    r = iesys_gen_auths(esysContext, pcrHandleNode, NULL, NULL, &auths);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Error in computation of auth values");
     esysContext->authsCount = auths.count;
     r = Tss2_Sys_SetCmdAuths(esysContext->sys, &auths);
-    if (r != TSS2_RC_SUCCESS) {
-        return r;
-    }
+    return_state_if_error(r, _ESYS_STATE_INIT, "SAPI error on SetCmdAuths");
 
+    /* Trigger execution and finish the async invocation */
     r = Tss2_Sys_ExecuteAsync(esysContext->sys);
-    return_if_error(r, "Finish (Execute Async)");
+    return_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Finish (Execute Async)");
 
     esysContext->state = _ESYS_STATE_SENT;
 
@@ -217,32 +222,42 @@
     TPML_DIGEST_VALUES **digests)
 {
     LOG_TRACE("complete");
+    TSS2_RC r;
     if (esysContext == NULL) {
         LOG_ERROR("esyscontext is NULL.");
         return TSS2_ESYS_RC_BAD_REFERENCE;
     }
+
+    /* Check for correct sequence and set sequence to irregular for now */
     if (esysContext->state != _ESYS_STATE_SENT) {
         LOG_ERROR("Esys called in bad sequence.");
         return TSS2_ESYS_RC_BAD_SEQUENCE;
     }
-    TSS2_RC r;
+    esysContext->state = _ESYS_STATE_INTERNALERROR;
+
+    /* Allocate memory for response parameters */
     if (digests != NULL) {
         *digests = calloc(sizeof(TPML_DIGEST_VALUES), 1);
         if (*digests == NULL) {
             return_error(TSS2_ESYS_RC_MEMORY, "Out of memory");
         }
     }
+
+    /*Receive the TPM response and handle resubmissions if necessary. */
     r = Tss2_Sys_ExecuteFinish(esysContext->sys, esysContext->timeout);
     if ((r & ~TSS2_RC_LAYER_MASK) == TSS2_BASE_RC_TRY_AGAIN) {
         LOG_DEBUG("A layer below returned TRY_AGAIN: %" PRIx32, r);
+        esysContext->state = _ESYS_STATE_SENT;
         goto error_cleanup;
     }
+    /* This block handle the resubmission of TPM commands given a certain set of
+     * TPM response codes. */
     if (r == TPM2_RC_RETRY || r == TPM2_RC_TESTING || r == TPM2_RC_YIELDED) {
         LOG_DEBUG("TPM returned RETRY, TESTING or YIELDED, which triggers a "
             "resubmission: %" PRIx32, r);
         if (esysContext->submissionCount >= _ESYS_MAX_SUBMISSIONS) {
-            LOG_WARNING("Maximum number of resubmissions has been reached.");
-            esysContext->state = _ESYS_STATE_ERRORRESPONSE;
+            LOG_WARNING("Maximum number of (re)submissions has been reached.");
+            esysContext->state = _ESYS_STATE_INIT;
             goto error_cleanup;
         }
         esysContext->state = _ESYS_STATE_RESUBMISSION;
@@ -253,22 +268,32 @@
                 esysContext->session_type[2],
                 esysContext->in.PCR_Event.eventData);
         if (r != TSS2_RC_SUCCESS) {
-            LOG_ERROR("Error attempting to resubmit");
+            LOG_WARNING("Error attempting to resubmit");
+            /* We do not set esysContext->state here but inherit the most recent
+             * state of the _async function. */
             goto error_cleanup;
         }
         r = TSS2_ESYS_RC_TRY_AGAIN;
+        LOG_DEBUG("Resubmission initiated and returning RC_TRY_AGAIN.");
         goto error_cleanup;
     }
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error finish (ExecuteFinish) PCR_Event");
+    /* The following is the "regular error" handling. */
+    if (r != TSS2_RC_SUCCESS && (r & TSS2_RC_LAYER_MASK) == 0) {
+        LOG_WARNING("Received TPM Error");
+        esysContext->state = _ESYS_STATE_INIT;
+        goto error_cleanup;
+    } else if (r != TSS2_RC_SUCCESS) {
+        LOG_ERROR("Received a non-TPM Error");
+        esysContext->state = _ESYS_STATE_INTERNALERROR;
         goto error_cleanup;
     }
+
     /*
      * Now the verification of the response (hmac check) and if necessary the
-     * parameter decryption have to be done
+     * parameter decryption have to be done.
      */
     r = iesys_check_response(esysContext);
-    goto_if_error(r, "Error: check response",
+    goto_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Error: check response",
                       error_cleanup);
     /*
      * After the verification of the response we call the complete function
@@ -276,17 +301,17 @@
      */
     r = Tss2_Sys_PCR_Event_Complete(esysContext->sys,
                 (digests != NULL) ? *digests : NULL);
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error finish (ExecuteFinish) PCR_Event: %" PRIx32, r);
-        esysContext->state = _ESYS_STATE_ERRORRESPONSE;
-        goto error_cleanup;;
-    }
-    esysContext->state = _ESYS_STATE_FINISHED;
+    goto_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Received error from SAPI"
+                        " unmarshalling" ,error_cleanup);
+    esysContext->state = _ESYS_STATE_INIT;
+    LOG_DEBUG("context=%p, digests=%p",
+              esysContext, digests);
 
-    return r;
+    return TSS2_RC_SUCCESS;
 
 error_cleanup:
     if (digests != NULL)
         SAFE_FREE(*digests);
+
     return r;
 }
diff --git a/src/tss2-esys/api/Esys_PCR_Extend.c b/src/tss2-esys/api/Esys_PCR_Extend.c
index 7d6703c..e81dbde 100644
--- a/src/tss2-esys/api/Esys_PCR_Extend.c
+++ b/src/tss2-esys/api/Esys_PCR_Extend.c
@@ -148,6 +148,7 @@
     TSS2L_SYS_AUTH_COMMAND auths;
     RSRC_NODE_T *pcrHandleNode;
 
+    /* Check context, sequence correctness and set state to error for now */
     if (esysContext == NULL) {
         LOG_ERROR("esyscontext is NULL.");
         return TSS2_ESYS_RC_BAD_REFERENCE;
@@ -155,38 +156,42 @@
     r = iesys_check_sequence_async(esysContext);
     if (r != TSS2_RC_SUCCESS)
         return r;
-    r = check_session_feasability(shandle1, shandle2, shandle3, 1);
-    return_if_error(r, "Check session usage");
+    esysContext->state = _ESYS_STATE_INTERNALERROR;
 
+    /* Check and store input parameters */
+    r = check_session_feasability(shandle1, shandle2, shandle3, 1);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Check session usage");
     store_input_parameters(esysContext, pcrHandle,
                 digests);
+
+    /* Retrieve the metadata objects for provided handles */
     r = esys_GetResourceObject(esysContext, pcrHandle, &pcrHandleNode);
-    if (r != TPM2_RC_SUCCESS)
-        return r;
+    return_state_if_error(r, _ESYS_STATE_INIT, "pcrHandle unknown.");
+
+    /* Initial invocation of SAPI to prepare the command buffer with parameters */
     r = Tss2_Sys_PCR_Extend_Prepare(esysContext->sys,
                 (pcrHandleNode == NULL) ? TPM2_RH_NULL : pcrHandleNode->rsrc.handle,
                 digests);
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error async PCR_Extend");
-        return r;
-    }
-    r = init_session_tab(esysContext, shandle1, shandle2, shandle3);
-    return_if_error(r, "Initialize session resources");
+    return_state_if_error(r, _ESYS_STATE_INIT, "SAPI Prepare returned error.");
 
+    /* Calculate the cpHash Values */
+    r = init_session_tab(esysContext, shandle1, shandle2, shandle3);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Initialize session resources");
     iesys_compute_session_value(esysContext->session_tab[0],
                 &pcrHandleNode->rsrc.name, &pcrHandleNode->auth);
     iesys_compute_session_value(esysContext->session_tab[1], NULL, NULL);
-    r = iesys_gen_auths(esysContext, pcrHandleNode, NULL, NULL, &auths);
-    return_if_error(r, "Error in computation of auth values");
+    iesys_compute_session_value(esysContext->session_tab[2], NULL, NULL);
 
+    /* Generate the auth values and set them in the SAPI command buffer */
+    r = iesys_gen_auths(esysContext, pcrHandleNode, NULL, NULL, &auths);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Error in computation of auth values");
     esysContext->authsCount = auths.count;
     r = Tss2_Sys_SetCmdAuths(esysContext->sys, &auths);
-    if (r != TSS2_RC_SUCCESS) {
-        return r;
-    }
+    return_state_if_error(r, _ESYS_STATE_INIT, "SAPI error on SetCmdAuths");
 
+    /* Trigger execution and finish the async invocation */
     r = Tss2_Sys_ExecuteAsync(esysContext->sys);
-    return_if_error(r, "Finish (Execute Async)");
+    return_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Finish (Execute Async)");
 
     esysContext->state = _ESYS_STATE_SENT;
 
@@ -210,26 +215,34 @@
     ESYS_CONTEXT *esysContext)
 {
     LOG_TRACE("complete");
+    TSS2_RC r;
     if (esysContext == NULL) {
         LOG_ERROR("esyscontext is NULL.");
         return TSS2_ESYS_RC_BAD_REFERENCE;
     }
+
+    /* Check for correct sequence and set sequence to irregular for now */
     if (esysContext->state != _ESYS_STATE_SENT) {
         LOG_ERROR("Esys called in bad sequence.");
         return TSS2_ESYS_RC_BAD_SEQUENCE;
     }
-    TSS2_RC r;
+    esysContext->state = _ESYS_STATE_INTERNALERROR;
+
+    /*Receive the TPM response and handle resubmissions if necessary. */
     r = Tss2_Sys_ExecuteFinish(esysContext->sys, esysContext->timeout);
     if ((r & ~TSS2_RC_LAYER_MASK) == TSS2_BASE_RC_TRY_AGAIN) {
         LOG_DEBUG("A layer below returned TRY_AGAIN: %" PRIx32, r);
+        esysContext->state = _ESYS_STATE_SENT;
         return r;
     }
+    /* This block handle the resubmission of TPM commands given a certain set of
+     * TPM response codes. */
     if (r == TPM2_RC_RETRY || r == TPM2_RC_TESTING || r == TPM2_RC_YIELDED) {
         LOG_DEBUG("TPM returned RETRY, TESTING or YIELDED, which triggers a "
             "resubmission: %" PRIx32, r);
         if (esysContext->submissionCount >= _ESYS_MAX_SUBMISSIONS) {
-            LOG_WARNING("Maximum number of resubmissions has been reached.");
-            esysContext->state = _ESYS_STATE_ERRORRESPONSE;
+            LOG_WARNING("Maximum number of (re)submissions has been reached.");
+            esysContext->state = _ESYS_STATE_INIT;
             return r;
         }
         esysContext->state = _ESYS_STATE_RESUBMISSION;
@@ -240,33 +253,42 @@
                 esysContext->session_type[2],
                 esysContext->in.PCR_Extend.digests);
         if (r != TSS2_RC_SUCCESS) {
-            LOG_ERROR("Error attempting to resubmit");
+            LOG_WARNING("Error attempting to resubmit");
+            /* We do not set esysContext->state here but inherit the most recent
+             * state of the _async function. */
             return r;
         }
         r = TSS2_ESYS_RC_TRY_AGAIN;
+        LOG_DEBUG("Resubmission initiated and returning RC_TRY_AGAIN.");
         return r;
     }
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error finish (ExecuteFinish) PCR_Extend");
+    /* The following is the "regular error" handling. */
+    if (r != TSS2_RC_SUCCESS && (r & TSS2_RC_LAYER_MASK) == 0) {
+        LOG_WARNING("Received TPM Error");
+        esysContext->state = _ESYS_STATE_INIT;
+        return r;
+    } else if (r != TSS2_RC_SUCCESS) {
+        LOG_ERROR("Received a non-TPM Error");
+        esysContext->state = _ESYS_STATE_INTERNALERROR;
         return r;
     }
+
     /*
      * Now the verification of the response (hmac check) and if necessary the
-     * parameter decryption have to be done
+     * parameter decryption have to be done.
      */
     r = iesys_check_response(esysContext);
-    return_if_error(r, "Error: check response");
+    return_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Error: check response");
     /*
      * After the verification of the response we call the complete function
      * to deliver the result.
      */
     r = Tss2_Sys_PCR_Extend_Complete(esysContext->sys);
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error finish (ExecuteFinish) PCR_Extend: %" PRIx32, r);
-        esysContext->state = _ESYS_STATE_ERRORRESPONSE;
-        return r;;
-    }
-    esysContext->state = _ESYS_STATE_FINISHED;
+    return_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Received error from SAPI"
+                        " unmarshalling" );
+    esysContext->state = _ESYS_STATE_INIT;
+    LOG_DEBUG("context=%p",
+              esysContext);
 
-    return r;
+    return TSS2_RC_SUCCESS;
 }
diff --git a/src/tss2-esys/api/Esys_PCR_Read.c b/src/tss2-esys/api/Esys_PCR_Read.c
index c9b7f29..edfdf17 100644
--- a/src/tss2-esys/api/Esys_PCR_Read.c
+++ b/src/tss2-esys/api/Esys_PCR_Read.c
@@ -150,6 +150,7 @@
     TSS2_RC r;
     TSS2L_SYS_AUTH_COMMAND auths;
 
+    /* Check context, sequence correctness and set state to error for now */
     if (esysContext == NULL) {
         LOG_ERROR("esyscontext is NULL.");
         return TSS2_ESYS_RC_BAD_REFERENCE;
@@ -157,32 +158,36 @@
     r = iesys_check_sequence_async(esysContext);
     if (r != TSS2_RC_SUCCESS)
         return r;
-    r = check_session_feasability(shandle1, shandle2, shandle3, 0);
-    return_if_error(r, "Check session usage");
+    esysContext->state = _ESYS_STATE_INTERNALERROR;
 
+    /* Check and store input parameters */
+    r = check_session_feasability(shandle1, shandle2, shandle3, 0);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Check session usage");
     store_input_parameters(esysContext,
                 pcrSelectionIn);
+
+    /* Initial invocation of SAPI to prepare the command buffer with parameters */
     r = Tss2_Sys_PCR_Read_Prepare(esysContext->sys,
                 pcrSelectionIn);
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error async PCR_Read");
-        return r;
-    }
+    return_state_if_error(r, _ESYS_STATE_INIT, "SAPI Prepare returned error.");
+
+    /* Calculate the cpHash Values */
     r = init_session_tab(esysContext, shandle1, shandle2, shandle3);
-    return_if_error(r, "Initialize session resources");
-
+    return_state_if_error(r, _ESYS_STATE_INIT, "Initialize session resources");
     iesys_compute_session_value(esysContext->session_tab[0], NULL, NULL);
-    r = iesys_gen_auths(esysContext, NULL, NULL, NULL, &auths);
-    return_if_error(r, "Error in computation of auth values");
+    iesys_compute_session_value(esysContext->session_tab[1], NULL, NULL);
+    iesys_compute_session_value(esysContext->session_tab[2], NULL, NULL);
 
+    /* Generate the auth values and set them in the SAPI command buffer */
+    r = iesys_gen_auths(esysContext, NULL, NULL, NULL, &auths);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Error in computation of auth values");
     esysContext->authsCount = auths.count;
     r = Tss2_Sys_SetCmdAuths(esysContext->sys, &auths);
-    if (r != TSS2_RC_SUCCESS) {
-        return r;
-    }
+    return_state_if_error(r, _ESYS_STATE_INIT, "SAPI error on SetCmdAuths");
 
+    /* Trigger execution and finish the async invocation */
     r = Tss2_Sys_ExecuteAsync(esysContext->sys);
-    return_if_error(r, "Finish (Execute Async)");
+    return_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Finish (Execute Async)");
 
     esysContext->state = _ESYS_STATE_SENT;
 
@@ -215,15 +220,20 @@
     TPML_DIGEST **pcrValues)
 {
     LOG_TRACE("complete");
+    TSS2_RC r;
     if (esysContext == NULL) {
         LOG_ERROR("esyscontext is NULL.");
         return TSS2_ESYS_RC_BAD_REFERENCE;
     }
+
+    /* Check for correct sequence and set sequence to irregular for now */
     if (esysContext->state != _ESYS_STATE_SENT) {
         LOG_ERROR("Esys called in bad sequence.");
         return TSS2_ESYS_RC_BAD_SEQUENCE;
     }
-    TSS2_RC r;
+    esysContext->state = _ESYS_STATE_INTERNALERROR;
+
+    /* Allocate memory for response parameters */
     if (pcrSelectionOut != NULL) {
         *pcrSelectionOut = calloc(sizeof(TPML_PCR_SELECTION), 1);
         if (*pcrSelectionOut == NULL) {
@@ -236,17 +246,22 @@
             goto_error(r, TSS2_ESYS_RC_MEMORY, "Out of memory", error_cleanup);
         }
     }
+
+    /*Receive the TPM response and handle resubmissions if necessary. */
     r = Tss2_Sys_ExecuteFinish(esysContext->sys, esysContext->timeout);
     if ((r & ~TSS2_RC_LAYER_MASK) == TSS2_BASE_RC_TRY_AGAIN) {
         LOG_DEBUG("A layer below returned TRY_AGAIN: %" PRIx32, r);
+        esysContext->state = _ESYS_STATE_SENT;
         goto error_cleanup;
     }
+    /* This block handle the resubmission of TPM commands given a certain set of
+     * TPM response codes. */
     if (r == TPM2_RC_RETRY || r == TPM2_RC_TESTING || r == TPM2_RC_YIELDED) {
         LOG_DEBUG("TPM returned RETRY, TESTING or YIELDED, which triggers a "
             "resubmission: %" PRIx32, r);
         if (esysContext->submissionCount >= _ESYS_MAX_SUBMISSIONS) {
-            LOG_WARNING("Maximum number of resubmissions has been reached.");
-            esysContext->state = _ESYS_STATE_ERRORRESPONSE;
+            LOG_WARNING("Maximum number of (re)submissions has been reached.");
+            esysContext->state = _ESYS_STATE_INIT;
             goto error_cleanup;
         }
         esysContext->state = _ESYS_STATE_RESUBMISSION;
@@ -256,22 +271,32 @@
                 esysContext->session_type[2],
                 esysContext->in.PCR_Read.pcrSelectionIn);
         if (r != TSS2_RC_SUCCESS) {
-            LOG_ERROR("Error attempting to resubmit");
+            LOG_WARNING("Error attempting to resubmit");
+            /* We do not set esysContext->state here but inherit the most recent
+             * state of the _async function. */
             goto error_cleanup;
         }
         r = TSS2_ESYS_RC_TRY_AGAIN;
+        LOG_DEBUG("Resubmission initiated and returning RC_TRY_AGAIN.");
         goto error_cleanup;
     }
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error finish (ExecuteFinish) PCR_Read");
+    /* The following is the "regular error" handling. */
+    if (r != TSS2_RC_SUCCESS && (r & TSS2_RC_LAYER_MASK) == 0) {
+        LOG_WARNING("Received TPM Error");
+        esysContext->state = _ESYS_STATE_INIT;
+        goto error_cleanup;
+    } else if (r != TSS2_RC_SUCCESS) {
+        LOG_ERROR("Received a non-TPM Error");
+        esysContext->state = _ESYS_STATE_INTERNALERROR;
         goto error_cleanup;
     }
+
     /*
      * Now the verification of the response (hmac check) and if necessary the
-     * parameter decryption have to be done
+     * parameter decryption have to be done.
      */
     r = iesys_check_response(esysContext);
-    goto_if_error(r, "Error: check response",
+    goto_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Error: check response",
                       error_cleanup);
     /*
      * After the verification of the response we call the complete function
@@ -281,19 +306,21 @@
                 pcrUpdateCounter,
                 (pcrSelectionOut != NULL) ? *pcrSelectionOut : NULL,
                 (pcrValues != NULL) ? *pcrValues : NULL);
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error finish (ExecuteFinish) PCR_Read: %" PRIx32, r);
-        esysContext->state = _ESYS_STATE_ERRORRESPONSE;
-        goto error_cleanup;;
-    }
-    esysContext->state = _ESYS_STATE_FINISHED;
+    goto_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Received error from SAPI"
+                        " unmarshalling" ,error_cleanup);
+    esysContext->state = _ESYS_STATE_INIT;
+    LOG_DEBUG("context=%p, pcrUpdateCounter=%p, pcrSelectionOut=%p,"
+              "pcrValues=%p",
+              esysContext, pcrUpdateCounter, pcrSelectionOut,
+              pcrValues);
 
-    return r;
+    return TSS2_RC_SUCCESS;
 
 error_cleanup:
     if (pcrSelectionOut != NULL)
         SAFE_FREE(*pcrSelectionOut);
     if (pcrValues != NULL)
         SAFE_FREE(*pcrValues);
+
     return r;
 }
diff --git a/src/tss2-esys/api/Esys_PCR_Reset.c b/src/tss2-esys/api/Esys_PCR_Reset.c
index 63a2bde..7af0755 100644
--- a/src/tss2-esys/api/Esys_PCR_Reset.c
+++ b/src/tss2-esys/api/Esys_PCR_Reset.c
@@ -135,6 +135,7 @@
     TSS2L_SYS_AUTH_COMMAND auths;
     RSRC_NODE_T *pcrHandleNode;
 
+    /* Check context, sequence correctness and set state to error for now */
     if (esysContext == NULL) {
         LOG_ERROR("esyscontext is NULL.");
         return TSS2_ESYS_RC_BAD_REFERENCE;
@@ -142,35 +143,40 @@
     r = iesys_check_sequence_async(esysContext);
     if (r != TSS2_RC_SUCCESS)
         return r;
-    r = check_session_feasability(shandle1, shandle2, shandle3, 1);
-    return_if_error(r, "Check session usage");
+    esysContext->state = _ESYS_STATE_INTERNALERROR;
 
+    /* Check and store input parameters */
+    r = check_session_feasability(shandle1, shandle2, shandle3, 1);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Check session usage");
     store_input_parameters(esysContext, pcrHandle);
+
+    /* Retrieve the metadata objects for provided handles */
     r = esys_GetResourceObject(esysContext, pcrHandle, &pcrHandleNode);
-    if (r != TPM2_RC_SUCCESS)
-        return r;
+    return_state_if_error(r, _ESYS_STATE_INIT, "pcrHandle unknown.");
+
+    /* Initial invocation of SAPI to prepare the command buffer with parameters */
     r = Tss2_Sys_PCR_Reset_Prepare(esysContext->sys,
                 (pcrHandleNode == NULL) ? TPM2_RH_NULL : pcrHandleNode->rsrc.handle);
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error async PCR_Reset");
-        return r;
-    }
-    r = init_session_tab(esysContext, shandle1, shandle2, shandle3);
-    return_if_error(r, "Initialize session resources");
+    return_state_if_error(r, _ESYS_STATE_INIT, "SAPI Prepare returned error.");
 
+    /* Calculate the cpHash Values */
+    r = init_session_tab(esysContext, shandle1, shandle2, shandle3);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Initialize session resources");
     iesys_compute_session_value(esysContext->session_tab[0],
                 &pcrHandleNode->rsrc.name, &pcrHandleNode->auth);
-    r = iesys_gen_auths(esysContext, pcrHandleNode, NULL, NULL, &auths);
-    return_if_error(r, "Error in computation of auth values");
+    iesys_compute_session_value(esysContext->session_tab[1], NULL, NULL);
+    iesys_compute_session_value(esysContext->session_tab[2], NULL, NULL);
 
+    /* Generate the auth values and set them in the SAPI command buffer */
+    r = iesys_gen_auths(esysContext, pcrHandleNode, NULL, NULL, &auths);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Error in computation of auth values");
     esysContext->authsCount = auths.count;
     r = Tss2_Sys_SetCmdAuths(esysContext->sys, &auths);
-    if (r != TSS2_RC_SUCCESS) {
-        return r;
-    }
+    return_state_if_error(r, _ESYS_STATE_INIT, "SAPI error on SetCmdAuths");
 
+    /* Trigger execution and finish the async invocation */
     r = Tss2_Sys_ExecuteAsync(esysContext->sys);
-    return_if_error(r, "Finish (Execute Async)");
+    return_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Finish (Execute Async)");
 
     esysContext->state = _ESYS_STATE_SENT;
 
@@ -194,26 +200,34 @@
     ESYS_CONTEXT *esysContext)
 {
     LOG_TRACE("complete");
+    TSS2_RC r;
     if (esysContext == NULL) {
         LOG_ERROR("esyscontext is NULL.");
         return TSS2_ESYS_RC_BAD_REFERENCE;
     }
+
+    /* Check for correct sequence and set sequence to irregular for now */
     if (esysContext->state != _ESYS_STATE_SENT) {
         LOG_ERROR("Esys called in bad sequence.");
         return TSS2_ESYS_RC_BAD_SEQUENCE;
     }
-    TSS2_RC r;
+    esysContext->state = _ESYS_STATE_INTERNALERROR;
+
+    /*Receive the TPM response and handle resubmissions if necessary. */
     r = Tss2_Sys_ExecuteFinish(esysContext->sys, esysContext->timeout);
     if ((r & ~TSS2_RC_LAYER_MASK) == TSS2_BASE_RC_TRY_AGAIN) {
         LOG_DEBUG("A layer below returned TRY_AGAIN: %" PRIx32, r);
+        esysContext->state = _ESYS_STATE_SENT;
         return r;
     }
+    /* This block handle the resubmission of TPM commands given a certain set of
+     * TPM response codes. */
     if (r == TPM2_RC_RETRY || r == TPM2_RC_TESTING || r == TPM2_RC_YIELDED) {
         LOG_DEBUG("TPM returned RETRY, TESTING or YIELDED, which triggers a "
             "resubmission: %" PRIx32, r);
         if (esysContext->submissionCount >= _ESYS_MAX_SUBMISSIONS) {
-            LOG_WARNING("Maximum number of resubmissions has been reached.");
-            esysContext->state = _ESYS_STATE_ERRORRESPONSE;
+            LOG_WARNING("Maximum number of (re)submissions has been reached.");
+            esysContext->state = _ESYS_STATE_INIT;
             return r;
         }
         esysContext->state = _ESYS_STATE_RESUBMISSION;
@@ -223,33 +237,42 @@
                 esysContext->session_type[1],
                 esysContext->session_type[2]);
         if (r != TSS2_RC_SUCCESS) {
-            LOG_ERROR("Error attempting to resubmit");
+            LOG_WARNING("Error attempting to resubmit");
+            /* We do not set esysContext->state here but inherit the most recent
+             * state of the _async function. */
             return r;
         }
         r = TSS2_ESYS_RC_TRY_AGAIN;
+        LOG_DEBUG("Resubmission initiated and returning RC_TRY_AGAIN.");
         return r;
     }
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error finish (ExecuteFinish) PCR_Reset");
+    /* The following is the "regular error" handling. */
+    if (r != TSS2_RC_SUCCESS && (r & TSS2_RC_LAYER_MASK) == 0) {
+        LOG_WARNING("Received TPM Error");
+        esysContext->state = _ESYS_STATE_INIT;
+        return r;
+    } else if (r != TSS2_RC_SUCCESS) {
+        LOG_ERROR("Received a non-TPM Error");
+        esysContext->state = _ESYS_STATE_INTERNALERROR;
         return r;
     }
+
     /*
      * Now the verification of the response (hmac check) and if necessary the
-     * parameter decryption have to be done
+     * parameter decryption have to be done.
      */
     r = iesys_check_response(esysContext);
-    return_if_error(r, "Error: check response");
+    return_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Error: check response");
     /*
      * After the verification of the response we call the complete function
      * to deliver the result.
      */
     r = Tss2_Sys_PCR_Reset_Complete(esysContext->sys);
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error finish (ExecuteFinish) PCR_Reset: %" PRIx32, r);
-        esysContext->state = _ESYS_STATE_ERRORRESPONSE;
-        return r;;
-    }
-    esysContext->state = _ESYS_STATE_FINISHED;
+    return_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Received error from SAPI"
+                        " unmarshalling" );
+    esysContext->state = _ESYS_STATE_INIT;
+    LOG_DEBUG("context=%p",
+              esysContext);
 
-    return r;
+    return TSS2_RC_SUCCESS;
 }
diff --git a/src/tss2-esys/api/Esys_PCR_SetAuthPolicy.c b/src/tss2-esys/api/Esys_PCR_SetAuthPolicy.c
index d837279..f6a4f15 100644
--- a/src/tss2-esys/api/Esys_PCR_SetAuthPolicy.c
+++ b/src/tss2-esys/api/Esys_PCR_SetAuthPolicy.c
@@ -162,6 +162,7 @@
     TSS2L_SYS_AUTH_COMMAND auths;
     RSRC_NODE_T *authHandleNode;
 
+    /* Check context, sequence correctness and set state to error for now */
     if (esysContext == NULL) {
         LOG_ERROR("esyscontext is NULL.");
         return TSS2_ESYS_RC_BAD_REFERENCE;
@@ -169,43 +170,46 @@
     r = iesys_check_sequence_async(esysContext);
     if (r != TSS2_RC_SUCCESS)
         return r;
-    r = check_session_feasability(shandle1, shandle2, shandle3, 1);
-    return_if_error(r, "Check session usage");
+    esysContext->state = _ESYS_STATE_INTERNALERROR;
 
+    /* Check and store input parameters */
+    r = check_session_feasability(shandle1, shandle2, shandle3, 1);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Check session usage");
     store_input_parameters(esysContext, authHandle,
                 authPolicy,
                 hashAlg,
                 pcrNum);
+
+    /* Retrieve the metadata objects for provided handles */
     r = esys_GetResourceObject(esysContext, authHandle, &authHandleNode);
-    if (r != TPM2_RC_SUCCESS)
-        return r;
+    return_state_if_error(r, _ESYS_STATE_INIT, "authHandle unknown.");
+
+    /* Initial invocation of SAPI to prepare the command buffer with parameters */
     r = Tss2_Sys_PCR_SetAuthPolicy_Prepare(esysContext->sys,
                 (authHandleNode == NULL) ? TPM2_RH_NULL : authHandleNode->rsrc.handle,
                 authPolicy,
                 hashAlg,
                 pcrNum);
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error async PCR_SetAuthPolicy");
-        return r;
-    }
-    r = init_session_tab(esysContext, shandle1, shandle2, shandle3);
-    return_if_error(r, "Initialize session resources");
+    return_state_if_error(r, _ESYS_STATE_INIT, "SAPI Prepare returned error.");
 
+    /* Calculate the cpHash Values */
+    r = init_session_tab(esysContext, shandle1, shandle2, shandle3);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Initialize session resources");
     iesys_compute_session_value(esysContext->session_tab[0],
                 &authHandleNode->rsrc.name, &authHandleNode->auth);
     iesys_compute_session_value(esysContext->session_tab[1], NULL, NULL);
     iesys_compute_session_value(esysContext->session_tab[2], NULL, NULL);
-    r = iesys_gen_auths(esysContext, authHandleNode, NULL, NULL, &auths);
-    return_if_error(r, "Error in computation of auth values");
 
+    /* Generate the auth values and set them in the SAPI command buffer */
+    r = iesys_gen_auths(esysContext, authHandleNode, NULL, NULL, &auths);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Error in computation of auth values");
     esysContext->authsCount = auths.count;
     r = Tss2_Sys_SetCmdAuths(esysContext->sys, &auths);
-    if (r != TSS2_RC_SUCCESS) {
-        return r;
-    }
+    return_state_if_error(r, _ESYS_STATE_INIT, "SAPI error on SetCmdAuths");
 
+    /* Trigger execution and finish the async invocation */
     r = Tss2_Sys_ExecuteAsync(esysContext->sys);
-    return_if_error(r, "Finish (Execute Async)");
+    return_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Finish (Execute Async)");
 
     esysContext->state = _ESYS_STATE_SENT;
 
@@ -229,26 +233,34 @@
     ESYS_CONTEXT *esysContext)
 {
     LOG_TRACE("complete");
+    TSS2_RC r;
     if (esysContext == NULL) {
         LOG_ERROR("esyscontext is NULL.");
         return TSS2_ESYS_RC_BAD_REFERENCE;
     }
+
+    /* Check for correct sequence and set sequence to irregular for now */
     if (esysContext->state != _ESYS_STATE_SENT) {
         LOG_ERROR("Esys called in bad sequence.");
         return TSS2_ESYS_RC_BAD_SEQUENCE;
     }
-    TSS2_RC r;
+    esysContext->state = _ESYS_STATE_INTERNALERROR;
+
+    /*Receive the TPM response and handle resubmissions if necessary. */
     r = Tss2_Sys_ExecuteFinish(esysContext->sys, esysContext->timeout);
     if ((r & ~TSS2_RC_LAYER_MASK) == TSS2_BASE_RC_TRY_AGAIN) {
         LOG_DEBUG("A layer below returned TRY_AGAIN: %" PRIx32, r);
+        esysContext->state = _ESYS_STATE_SENT;
         return r;
     }
+    /* This block handle the resubmission of TPM commands given a certain set of
+     * TPM response codes. */
     if (r == TPM2_RC_RETRY || r == TPM2_RC_TESTING || r == TPM2_RC_YIELDED) {
         LOG_DEBUG("TPM returned RETRY, TESTING or YIELDED, which triggers a "
             "resubmission: %" PRIx32, r);
         if (esysContext->submissionCount >= _ESYS_MAX_SUBMISSIONS) {
-            LOG_WARNING("Maximum number of resubmissions has been reached.");
-            esysContext->state = _ESYS_STATE_ERRORRESPONSE;
+            LOG_WARNING("Maximum number of (re)submissions has been reached.");
+            esysContext->state = _ESYS_STATE_INIT;
             return r;
         }
         esysContext->state = _ESYS_STATE_RESUBMISSION;
@@ -261,33 +273,42 @@
                 esysContext->in.PCR_SetAuthPolicy.hashAlg,
                 esysContext->in.PCR_SetAuthPolicy.pcrNum);
         if (r != TSS2_RC_SUCCESS) {
-            LOG_ERROR("Error attempting to resubmit");
+            LOG_WARNING("Error attempting to resubmit");
+            /* We do not set esysContext->state here but inherit the most recent
+             * state of the _async function. */
             return r;
         }
         r = TSS2_ESYS_RC_TRY_AGAIN;
+        LOG_DEBUG("Resubmission initiated and returning RC_TRY_AGAIN.");
         return r;
     }
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error finish (ExecuteFinish) PCR_SetAuthPolicy");
+    /* The following is the "regular error" handling. */
+    if (r != TSS2_RC_SUCCESS && (r & TSS2_RC_LAYER_MASK) == 0) {
+        LOG_WARNING("Received TPM Error");
+        esysContext->state = _ESYS_STATE_INIT;
+        return r;
+    } else if (r != TSS2_RC_SUCCESS) {
+        LOG_ERROR("Received a non-TPM Error");
+        esysContext->state = _ESYS_STATE_INTERNALERROR;
         return r;
     }
+
     /*
      * Now the verification of the response (hmac check) and if necessary the
-     * parameter decryption have to be done
+     * parameter decryption have to be done.
      */
     r = iesys_check_response(esysContext);
-    return_if_error(r, "Error: check response");
+    return_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Error: check response");
     /*
      * After the verification of the response we call the complete function
      * to deliver the result.
      */
     r = Tss2_Sys_PCR_SetAuthPolicy_Complete(esysContext->sys);
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error finish (ExecuteFinish) PCR_SetAuthPolicy: %" PRIx32, r);
-        esysContext->state = _ESYS_STATE_ERRORRESPONSE;
-        return r;;
-    }
-    esysContext->state = _ESYS_STATE_FINISHED;
+    return_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Received error from SAPI"
+                        " unmarshalling" );
+    esysContext->state = _ESYS_STATE_INIT;
+    LOG_DEBUG("context=%p",
+              esysContext);
 
-    return r;
+    return TSS2_RC_SUCCESS;
 }
diff --git a/src/tss2-esys/api/Esys_PCR_SetAuthValue.c b/src/tss2-esys/api/Esys_PCR_SetAuthValue.c
index 58ea727..7e84af1 100644
--- a/src/tss2-esys/api/Esys_PCR_SetAuthValue.c
+++ b/src/tss2-esys/api/Esys_PCR_SetAuthValue.c
@@ -148,6 +148,7 @@
     TSS2L_SYS_AUTH_COMMAND auths;
     RSRC_NODE_T *pcrHandleNode;
 
+    /* Check context, sequence correctness and set state to error for now */
     if (esysContext == NULL) {
         LOG_ERROR("esyscontext is NULL.");
         return TSS2_ESYS_RC_BAD_REFERENCE;
@@ -155,38 +156,42 @@
     r = iesys_check_sequence_async(esysContext);
     if (r != TSS2_RC_SUCCESS)
         return r;
-    r = check_session_feasability(shandle1, shandle2, shandle3, 1);
-    return_if_error(r, "Check session usage");
+    esysContext->state = _ESYS_STATE_INTERNALERROR;
 
+    /* Check and store input parameters */
+    r = check_session_feasability(shandle1, shandle2, shandle3, 1);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Check session usage");
     store_input_parameters(esysContext, pcrHandle,
                 auth);
+
+    /* Retrieve the metadata objects for provided handles */
     r = esys_GetResourceObject(esysContext, pcrHandle, &pcrHandleNode);
-    if (r != TPM2_RC_SUCCESS)
-        return r;
+    return_state_if_error(r, _ESYS_STATE_INIT, "pcrHandle unknown.");
+
+    /* Initial invocation of SAPI to prepare the command buffer with parameters */
     r = Tss2_Sys_PCR_SetAuthValue_Prepare(esysContext->sys,
                 (pcrHandleNode == NULL) ? TPM2_RH_NULL : pcrHandleNode->rsrc.handle,
                 auth);
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error async PCR_SetAuthValue");
-        return r;
-    }
-    r = init_session_tab(esysContext, shandle1, shandle2, shandle3);
-    return_if_error(r, "Initialize session resources");
+    return_state_if_error(r, _ESYS_STATE_INIT, "SAPI Prepare returned error.");
 
+    /* Calculate the cpHash Values */
+    r = init_session_tab(esysContext, shandle1, shandle2, shandle3);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Initialize session resources");
     iesys_compute_session_value(esysContext->session_tab[0],
                 &pcrHandleNode->rsrc.name, &pcrHandleNode->auth);
     iesys_compute_session_value(esysContext->session_tab[1], NULL, NULL);
-    r = iesys_gen_auths(esysContext, pcrHandleNode, NULL, NULL, &auths);
-    return_if_error(r, "Error in computation of auth values");
+    iesys_compute_session_value(esysContext->session_tab[2], NULL, NULL);
 
+    /* Generate the auth values and set them in the SAPI command buffer */
+    r = iesys_gen_auths(esysContext, pcrHandleNode, NULL, NULL, &auths);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Error in computation of auth values");
     esysContext->authsCount = auths.count;
     r = Tss2_Sys_SetCmdAuths(esysContext->sys, &auths);
-    if (r != TSS2_RC_SUCCESS) {
-        return r;
-    }
+    return_state_if_error(r, _ESYS_STATE_INIT, "SAPI error on SetCmdAuths");
 
+    /* Trigger execution and finish the async invocation */
     r = Tss2_Sys_ExecuteAsync(esysContext->sys);
-    return_if_error(r, "Finish (Execute Async)");
+    return_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Finish (Execute Async)");
 
     esysContext->state = _ESYS_STATE_SENT;
 
@@ -210,26 +215,34 @@
     ESYS_CONTEXT *esysContext)
 {
     LOG_TRACE("complete");
+    TSS2_RC r;
     if (esysContext == NULL) {
         LOG_ERROR("esyscontext is NULL.");
         return TSS2_ESYS_RC_BAD_REFERENCE;
     }
+
+    /* Check for correct sequence and set sequence to irregular for now */
     if (esysContext->state != _ESYS_STATE_SENT) {
         LOG_ERROR("Esys called in bad sequence.");
         return TSS2_ESYS_RC_BAD_SEQUENCE;
     }
-    TSS2_RC r;
+    esysContext->state = _ESYS_STATE_INTERNALERROR;
+
+    /*Receive the TPM response and handle resubmissions if necessary. */
     r = Tss2_Sys_ExecuteFinish(esysContext->sys, esysContext->timeout);
     if ((r & ~TSS2_RC_LAYER_MASK) == TSS2_BASE_RC_TRY_AGAIN) {
         LOG_DEBUG("A layer below returned TRY_AGAIN: %" PRIx32, r);
+        esysContext->state = _ESYS_STATE_SENT;
         return r;
     }
+    /* This block handle the resubmission of TPM commands given a certain set of
+     * TPM response codes. */
     if (r == TPM2_RC_RETRY || r == TPM2_RC_TESTING || r == TPM2_RC_YIELDED) {
         LOG_DEBUG("TPM returned RETRY, TESTING or YIELDED, which triggers a "
             "resubmission: %" PRIx32, r);
         if (esysContext->submissionCount >= _ESYS_MAX_SUBMISSIONS) {
-            LOG_WARNING("Maximum number of resubmissions has been reached.");
-            esysContext->state = _ESYS_STATE_ERRORRESPONSE;
+            LOG_WARNING("Maximum number of (re)submissions has been reached.");
+            esysContext->state = _ESYS_STATE_INIT;
             return r;
         }
         esysContext->state = _ESYS_STATE_RESUBMISSION;
@@ -240,33 +253,42 @@
                 esysContext->session_type[2],
                 esysContext->in.PCR_SetAuthValue.auth);
         if (r != TSS2_RC_SUCCESS) {
-            LOG_ERROR("Error attempting to resubmit");
+            LOG_WARNING("Error attempting to resubmit");
+            /* We do not set esysContext->state here but inherit the most recent
+             * state of the _async function. */
             return r;
         }
         r = TSS2_ESYS_RC_TRY_AGAIN;
+        LOG_DEBUG("Resubmission initiated and returning RC_TRY_AGAIN.");
         return r;
     }
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error finish (ExecuteFinish) PCR_SetAuthValue");
+    /* The following is the "regular error" handling. */
+    if (r != TSS2_RC_SUCCESS && (r & TSS2_RC_LAYER_MASK) == 0) {
+        LOG_WARNING("Received TPM Error");
+        esysContext->state = _ESYS_STATE_INIT;
+        return r;
+    } else if (r != TSS2_RC_SUCCESS) {
+        LOG_ERROR("Received a non-TPM Error");
+        esysContext->state = _ESYS_STATE_INTERNALERROR;
         return r;
     }
+
     /*
      * Now the verification of the response (hmac check) and if necessary the
-     * parameter decryption have to be done
+     * parameter decryption have to be done.
      */
     r = iesys_check_response(esysContext);
-    return_if_error(r, "Error: check response");
+    return_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Error: check response");
     /*
      * After the verification of the response we call the complete function
      * to deliver the result.
      */
     r = Tss2_Sys_PCR_SetAuthValue_Complete(esysContext->sys);
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error finish (ExecuteFinish) PCR_SetAuthValue: %" PRIx32, r);
-        esysContext->state = _ESYS_STATE_ERRORRESPONSE;
-        return r;;
-    }
-    esysContext->state = _ESYS_STATE_FINISHED;
+    return_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Received error from SAPI"
+                        " unmarshalling" );
+    esysContext->state = _ESYS_STATE_INIT;
+    LOG_DEBUG("context=%p",
+              esysContext);
 
-    return r;
+    return TSS2_RC_SUCCESS;
 }
diff --git a/src/tss2-esys/api/Esys_PP_Commands.c b/src/tss2-esys/api/Esys_PP_Commands.c
index bb7a9bb..033eb2d 100644
--- a/src/tss2-esys/api/Esys_PP_Commands.c
+++ b/src/tss2-esys/api/Esys_PP_Commands.c
@@ -161,6 +161,7 @@
     TSS2L_SYS_AUTH_COMMAND auths;
     RSRC_NODE_T *authNode;
 
+    /* Check context, sequence correctness and set state to error for now */
     if (esysContext == NULL) {
         LOG_ERROR("esyscontext is NULL.");
         return TSS2_ESYS_RC_BAD_REFERENCE;
@@ -168,41 +169,44 @@
     r = iesys_check_sequence_async(esysContext);
     if (r != TSS2_RC_SUCCESS)
         return r;
-    r = check_session_feasability(shandle1, shandle2, shandle3, 1);
-    return_if_error(r, "Check session usage");
+    esysContext->state = _ESYS_STATE_INTERNALERROR;
 
+    /* Check and store input parameters */
+    r = check_session_feasability(shandle1, shandle2, shandle3, 1);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Check session usage");
     store_input_parameters(esysContext, auth,
                 setList,
                 clearList);
+
+    /* Retrieve the metadata objects for provided handles */
     r = esys_GetResourceObject(esysContext, auth, &authNode);
-    if (r != TPM2_RC_SUCCESS)
-        return r;
+    return_state_if_error(r, _ESYS_STATE_INIT, "auth unknown.");
+
+    /* Initial invocation of SAPI to prepare the command buffer with parameters */
     r = Tss2_Sys_PP_Commands_Prepare(esysContext->sys,
                 (authNode == NULL) ? TPM2_RH_NULL : authNode->rsrc.handle,
                 setList,
                 clearList);
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error async PP_Commands");
-        return r;
-    }
-    r = init_session_tab(esysContext, shandle1, shandle2, shandle3);
-    return_if_error(r, "Initialize session resources");
+    return_state_if_error(r, _ESYS_STATE_INIT, "SAPI Prepare returned error.");
 
+    /* Calculate the cpHash Values */
+    r = init_session_tab(esysContext, shandle1, shandle2, shandle3);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Initialize session resources");
     iesys_compute_session_value(esysContext->session_tab[0],
                 &authNode->rsrc.name, &authNode->auth);
     iesys_compute_session_value(esysContext->session_tab[1], NULL, NULL);
     iesys_compute_session_value(esysContext->session_tab[2], NULL, NULL);
-    r = iesys_gen_auths(esysContext, authNode, NULL, NULL, &auths);
-    return_if_error(r, "Error in computation of auth values");
 
+    /* Generate the auth values and set them in the SAPI command buffer */
+    r = iesys_gen_auths(esysContext, authNode, NULL, NULL, &auths);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Error in computation of auth values");
     esysContext->authsCount = auths.count;
     r = Tss2_Sys_SetCmdAuths(esysContext->sys, &auths);
-    if (r != TSS2_RC_SUCCESS) {
-        return r;
-    }
+    return_state_if_error(r, _ESYS_STATE_INIT, "SAPI error on SetCmdAuths");
 
+    /* Trigger execution and finish the async invocation */
     r = Tss2_Sys_ExecuteAsync(esysContext->sys);
-    return_if_error(r, "Finish (Execute Async)");
+    return_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Finish (Execute Async)");
 
     esysContext->state = _ESYS_STATE_SENT;
 
@@ -226,26 +230,34 @@
     ESYS_CONTEXT *esysContext)
 {
     LOG_TRACE("complete");
+    TSS2_RC r;
     if (esysContext == NULL) {
         LOG_ERROR("esyscontext is NULL.");
         return TSS2_ESYS_RC_BAD_REFERENCE;
     }
+
+    /* Check for correct sequence and set sequence to irregular for now */
     if (esysContext->state != _ESYS_STATE_SENT) {
         LOG_ERROR("Esys called in bad sequence.");
         return TSS2_ESYS_RC_BAD_SEQUENCE;
     }
-    TSS2_RC r;
+    esysContext->state = _ESYS_STATE_INTERNALERROR;
+
+    /*Receive the TPM response and handle resubmissions if necessary. */
     r = Tss2_Sys_ExecuteFinish(esysContext->sys, esysContext->timeout);
     if ((r & ~TSS2_RC_LAYER_MASK) == TSS2_BASE_RC_TRY_AGAIN) {
         LOG_DEBUG("A layer below returned TRY_AGAIN: %" PRIx32, r);
+        esysContext->state = _ESYS_STATE_SENT;
         return r;
     }
+    /* This block handle the resubmission of TPM commands given a certain set of
+     * TPM response codes. */
     if (r == TPM2_RC_RETRY || r == TPM2_RC_TESTING || r == TPM2_RC_YIELDED) {
         LOG_DEBUG("TPM returned RETRY, TESTING or YIELDED, which triggers a "
             "resubmission: %" PRIx32, r);
         if (esysContext->submissionCount >= _ESYS_MAX_SUBMISSIONS) {
-            LOG_WARNING("Maximum number of resubmissions has been reached.");
-            esysContext->state = _ESYS_STATE_ERRORRESPONSE;
+            LOG_WARNING("Maximum number of (re)submissions has been reached.");
+            esysContext->state = _ESYS_STATE_INIT;
             return r;
         }
         esysContext->state = _ESYS_STATE_RESUBMISSION;
@@ -257,33 +269,42 @@
                 esysContext->in.PP_Commands.setList,
                 esysContext->in.PP_Commands.clearList);
         if (r != TSS2_RC_SUCCESS) {
-            LOG_ERROR("Error attempting to resubmit");
+            LOG_WARNING("Error attempting to resubmit");
+            /* We do not set esysContext->state here but inherit the most recent
+             * state of the _async function. */
             return r;
         }
         r = TSS2_ESYS_RC_TRY_AGAIN;
+        LOG_DEBUG("Resubmission initiated and returning RC_TRY_AGAIN.");
         return r;
     }
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error finish (ExecuteFinish) PP_Commands");
+    /* The following is the "regular error" handling. */
+    if (r != TSS2_RC_SUCCESS && (r & TSS2_RC_LAYER_MASK) == 0) {
+        LOG_WARNING("Received TPM Error");
+        esysContext->state = _ESYS_STATE_INIT;
+        return r;
+    } else if (r != TSS2_RC_SUCCESS) {
+        LOG_ERROR("Received a non-TPM Error");
+        esysContext->state = _ESYS_STATE_INTERNALERROR;
         return r;
     }
+
     /*
      * Now the verification of the response (hmac check) and if necessary the
-     * parameter decryption have to be done
+     * parameter decryption have to be done.
      */
     r = iesys_check_response(esysContext);
-    return_if_error(r, "Error: check response");
+    return_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Error: check response");
     /*
      * After the verification of the response we call the complete function
      * to deliver the result.
      */
     r = Tss2_Sys_PP_Commands_Complete(esysContext->sys);
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error finish (ExecuteFinish) PP_Commands: %" PRIx32, r);
-        esysContext->state = _ESYS_STATE_ERRORRESPONSE;
-        return r;;
-    }
-    esysContext->state = _ESYS_STATE_FINISHED;
+    return_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Received error from SAPI"
+                        " unmarshalling" );
+    esysContext->state = _ESYS_STATE_INIT;
+    LOG_DEBUG("context=%p",
+              esysContext);
 
-    return r;
+    return TSS2_RC_SUCCESS;
 }
diff --git a/src/tss2-esys/api/Esys_PolicyAuthValue.c b/src/tss2-esys/api/Esys_PolicyAuthValue.c
index 83f26e1..81fd236 100644
--- a/src/tss2-esys/api/Esys_PolicyAuthValue.c
+++ b/src/tss2-esys/api/Esys_PolicyAuthValue.c
@@ -135,6 +135,7 @@
     TSS2L_SYS_AUTH_COMMAND auths;
     RSRC_NODE_T *policySessionNode;
 
+    /* Check context, sequence correctness and set state to error for now */
     if (esysContext == NULL) {
         LOG_ERROR("esyscontext is NULL.");
         return TSS2_ESYS_RC_BAD_REFERENCE;
@@ -142,34 +143,39 @@
     r = iesys_check_sequence_async(esysContext);
     if (r != TSS2_RC_SUCCESS)
         return r;
-    r = check_session_feasability(shandle1, shandle2, shandle3, 0);
-    return_if_error(r, "Check session usage");
+    esysContext->state = _ESYS_STATE_INTERNALERROR;
 
+    /* Check and store input parameters */
+    r = check_session_feasability(shandle1, shandle2, shandle3, 0);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Check session usage");
     store_input_parameters(esysContext, policySession);
+
+    /* Retrieve the metadata objects for provided handles */
     r = esys_GetResourceObject(esysContext, policySession, &policySessionNode);
-    if (r != TPM2_RC_SUCCESS)
-        return r;
+    return_state_if_error(r, _ESYS_STATE_INIT, "policySession unknown.");
+
+    /* Initial invocation of SAPI to prepare the command buffer with parameters */
     r = Tss2_Sys_PolicyAuthValue_Prepare(esysContext->sys,
                 (policySessionNode == NULL) ? TPM2_RH_NULL : policySessionNode->rsrc.handle);
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error async PolicyAuthValue");
-        return r;
-    }
+    return_state_if_error(r, _ESYS_STATE_INIT, "SAPI Prepare returned error.");
+
+    /* Calculate the cpHash Values */
     r = init_session_tab(esysContext, shandle1, shandle2, shandle3);
-    return_if_error(r, "Initialize session resources");
-
+    return_state_if_error(r, _ESYS_STATE_INIT, "Initialize session resources");
     iesys_compute_session_value(esysContext->session_tab[0], NULL, NULL);
-    r = iesys_gen_auths(esysContext, policySessionNode, NULL, NULL, &auths);
-    return_if_error(r, "Error in computation of auth values");
+    iesys_compute_session_value(esysContext->session_tab[1], NULL, NULL);
+    iesys_compute_session_value(esysContext->session_tab[2], NULL, NULL);
 
+    /* Generate the auth values and set them in the SAPI command buffer */
+    r = iesys_gen_auths(esysContext, policySessionNode, NULL, NULL, &auths);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Error in computation of auth values");
     esysContext->authsCount = auths.count;
     r = Tss2_Sys_SetCmdAuths(esysContext->sys, &auths);
-    if (r != TSS2_RC_SUCCESS) {
-        return r;
-    }
+    return_state_if_error(r, _ESYS_STATE_INIT, "SAPI error on SetCmdAuths");
 
+    /* Trigger execution and finish the async invocation */
     r = Tss2_Sys_ExecuteAsync(esysContext->sys);
-    return_if_error(r, "Finish (Execute Async)");
+    return_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Finish (Execute Async)");
 
     esysContext->state = _ESYS_STATE_SENT;
 
@@ -193,26 +199,34 @@
     ESYS_CONTEXT *esysContext)
 {
     LOG_TRACE("complete");
+    TSS2_RC r;
     if (esysContext == NULL) {
         LOG_ERROR("esyscontext is NULL.");
         return TSS2_ESYS_RC_BAD_REFERENCE;
     }
+
+    /* Check for correct sequence and set sequence to irregular for now */
     if (esysContext->state != _ESYS_STATE_SENT) {
         LOG_ERROR("Esys called in bad sequence.");
         return TSS2_ESYS_RC_BAD_SEQUENCE;
     }
-    TSS2_RC r;
+    esysContext->state = _ESYS_STATE_INTERNALERROR;
+
+    /*Receive the TPM response and handle resubmissions if necessary. */
     r = Tss2_Sys_ExecuteFinish(esysContext->sys, esysContext->timeout);
     if ((r & ~TSS2_RC_LAYER_MASK) == TSS2_BASE_RC_TRY_AGAIN) {
         LOG_DEBUG("A layer below returned TRY_AGAIN: %" PRIx32, r);
+        esysContext->state = _ESYS_STATE_SENT;
         return r;
     }
+    /* This block handle the resubmission of TPM commands given a certain set of
+     * TPM response codes. */
     if (r == TPM2_RC_RETRY || r == TPM2_RC_TESTING || r == TPM2_RC_YIELDED) {
         LOG_DEBUG("TPM returned RETRY, TESTING or YIELDED, which triggers a "
             "resubmission: %" PRIx32, r);
         if (esysContext->submissionCount >= _ESYS_MAX_SUBMISSIONS) {
-            LOG_WARNING("Maximum number of resubmissions has been reached.");
-            esysContext->state = _ESYS_STATE_ERRORRESPONSE;
+            LOG_WARNING("Maximum number of (re)submissions has been reached.");
+            esysContext->state = _ESYS_STATE_INIT;
             return r;
         }
         esysContext->state = _ESYS_STATE_RESUBMISSION;
@@ -222,40 +236,50 @@
                 esysContext->session_type[1],
                 esysContext->session_type[2]);
         if (r != TSS2_RC_SUCCESS) {
-            LOG_ERROR("Error attempting to resubmit");
+            LOG_WARNING("Error attempting to resubmit");
+            /* We do not set esysContext->state here but inherit the most recent
+             * state of the _async function. */
             return r;
         }
         r = TSS2_ESYS_RC_TRY_AGAIN;
+        LOG_DEBUG("Resubmission initiated and returning RC_TRY_AGAIN.");
         return r;
     }
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error finish (ExecuteFinish) PolicyAuthValue");
+    /* The following is the "regular error" handling. */
+    if (r != TSS2_RC_SUCCESS && (r & TSS2_RC_LAYER_MASK) == 0) {
+        LOG_WARNING("Received TPM Error");
+        esysContext->state = _ESYS_STATE_INIT;
+        return r;
+    } else if (r != TSS2_RC_SUCCESS) {
+        LOG_ERROR("Received a non-TPM Error");
+        esysContext->state = _ESYS_STATE_INTERNALERROR;
         return r;
     }
+
     /*
      * Now the verification of the response (hmac check) and if necessary the
-     * parameter decryption have to be done
+     * parameter decryption have to be done.
      */
     r = iesys_check_response(esysContext);
-    return_if_error(r, "Error: check response");
+    return_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Error: check response");
     /*
      * After the verification of the response we call the complete function
      * to deliver the result.
      */
     r = Tss2_Sys_PolicyAuthValue_Complete(esysContext->sys);
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error finish (ExecuteFinish) PolicyAuthValue: %" PRIx32, r);
-        esysContext->state = _ESYS_STATE_ERRORRESPONSE;
-        return r;;
-    }
+    return_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Received error from SAPI"
+                        " unmarshalling" );
     ESYS_TR policySession = esysContext->in.PolicyAuthValue.policySession;
     RSRC_NODE_T *policySessionNode;
     r = esys_GetResourceObject(esysContext, policySession, &policySessionNode);
     return_if_error(r, "get resource");
 
     if (policySessionNode != NULL)
+        /* Indicate that the auth value has to be included in the hmac */
         policySessionNode->rsrc.misc.rsrc_session.type_policy_session = POLICY_AUTH;
-    esysContext->state = _ESYS_STATE_FINISHED;
+    esysContext->state = _ESYS_STATE_INIT;
+    LOG_DEBUG("context=%p",
+              esysContext);
 
-    return r;
+    return TSS2_RC_SUCCESS;
 }
diff --git a/src/tss2-esys/api/Esys_PolicyAuthorize.c b/src/tss2-esys/api/Esys_PolicyAuthorize.c
index dcd9472..0730f01 100644
--- a/src/tss2-esys/api/Esys_PolicyAuthorize.c
+++ b/src/tss2-esys/api/Esys_PolicyAuthorize.c
@@ -187,6 +187,7 @@
     TSS2L_SYS_AUTH_COMMAND auths;
     RSRC_NODE_T *policySessionNode;
 
+    /* Check context, sequence correctness and set state to error for now */
     if (esysContext == NULL) {
         LOG_ERROR("esyscontext is NULL.");
         return TSS2_ESYS_RC_BAD_REFERENCE;
@@ -194,44 +195,47 @@
     r = iesys_check_sequence_async(esysContext);
     if (r != TSS2_RC_SUCCESS)
         return r;
-    r = check_session_feasability(shandle1, shandle2, shandle3, 0);
-    return_if_error(r, "Check session usage");
+    esysContext->state = _ESYS_STATE_INTERNALERROR;
 
+    /* Check and store input parameters */
+    r = check_session_feasability(shandle1, shandle2, shandle3, 0);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Check session usage");
     store_input_parameters(esysContext, policySession,
                 approvedPolicy,
                 policyRef,
                 keySign,
                 checkTicket);
+
+    /* Retrieve the metadata objects for provided handles */
     r = esys_GetResourceObject(esysContext, policySession, &policySessionNode);
-    if (r != TPM2_RC_SUCCESS)
-        return r;
+    return_state_if_error(r, _ESYS_STATE_INIT, "policySession unknown.");
+
+    /* Initial invocation of SAPI to prepare the command buffer with parameters */
     r = Tss2_Sys_PolicyAuthorize_Prepare(esysContext->sys,
                 (policySessionNode == NULL) ? TPM2_RH_NULL : policySessionNode->rsrc.handle,
                 approvedPolicy,
                 policyRef,
                 keySign,
                 checkTicket);
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error async PolicyAuthorize");
-        return r;
-    }
-    r = init_session_tab(esysContext, shandle1, shandle2, shandle3);
-    return_if_error(r, "Initialize session resources");
+    return_state_if_error(r, _ESYS_STATE_INIT, "SAPI Prepare returned error.");
 
+    /* Calculate the cpHash Values */
+    r = init_session_tab(esysContext, shandle1, shandle2, shandle3);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Initialize session resources");
     iesys_compute_session_value(esysContext->session_tab[0], NULL, NULL);
     iesys_compute_session_value(esysContext->session_tab[1], NULL, NULL);
     iesys_compute_session_value(esysContext->session_tab[2], NULL, NULL);
-    r = iesys_gen_auths(esysContext, policySessionNode, NULL, NULL, &auths);
-    return_if_error(r, "Error in computation of auth values");
 
+    /* Generate the auth values and set them in the SAPI command buffer */
+    r = iesys_gen_auths(esysContext, policySessionNode, NULL, NULL, &auths);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Error in computation of auth values");
     esysContext->authsCount = auths.count;
     r = Tss2_Sys_SetCmdAuths(esysContext->sys, &auths);
-    if (r != TSS2_RC_SUCCESS) {
-        return r;
-    }
+    return_state_if_error(r, _ESYS_STATE_INIT, "SAPI error on SetCmdAuths");
 
+    /* Trigger execution and finish the async invocation */
     r = Tss2_Sys_ExecuteAsync(esysContext->sys);
-    return_if_error(r, "Finish (Execute Async)");
+    return_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Finish (Execute Async)");
 
     esysContext->state = _ESYS_STATE_SENT;
 
@@ -255,26 +259,34 @@
     ESYS_CONTEXT *esysContext)
 {
     LOG_TRACE("complete");
+    TSS2_RC r;
     if (esysContext == NULL) {
         LOG_ERROR("esyscontext is NULL.");
         return TSS2_ESYS_RC_BAD_REFERENCE;
     }
+
+    /* Check for correct sequence and set sequence to irregular for now */
     if (esysContext->state != _ESYS_STATE_SENT) {
         LOG_ERROR("Esys called in bad sequence.");
         return TSS2_ESYS_RC_BAD_SEQUENCE;
     }
-    TSS2_RC r;
+    esysContext->state = _ESYS_STATE_INTERNALERROR;
+
+    /*Receive the TPM response and handle resubmissions if necessary. */
     r = Tss2_Sys_ExecuteFinish(esysContext->sys, esysContext->timeout);
     if ((r & ~TSS2_RC_LAYER_MASK) == TSS2_BASE_RC_TRY_AGAIN) {
         LOG_DEBUG("A layer below returned TRY_AGAIN: %" PRIx32, r);
+        esysContext->state = _ESYS_STATE_SENT;
         return r;
     }
+    /* This block handle the resubmission of TPM commands given a certain set of
+     * TPM response codes. */
     if (r == TPM2_RC_RETRY || r == TPM2_RC_TESTING || r == TPM2_RC_YIELDED) {
         LOG_DEBUG("TPM returned RETRY, TESTING or YIELDED, which triggers a "
             "resubmission: %" PRIx32, r);
         if (esysContext->submissionCount >= _ESYS_MAX_SUBMISSIONS) {
-            LOG_WARNING("Maximum number of resubmissions has been reached.");
-            esysContext->state = _ESYS_STATE_ERRORRESPONSE;
+            LOG_WARNING("Maximum number of (re)submissions has been reached.");
+            esysContext->state = _ESYS_STATE_INIT;
             return r;
         }
         esysContext->state = _ESYS_STATE_RESUBMISSION;
@@ -288,33 +300,42 @@
                 esysContext->in.PolicyAuthorize.keySign,
                 esysContext->in.PolicyAuthorize.checkTicket);
         if (r != TSS2_RC_SUCCESS) {
-            LOG_ERROR("Error attempting to resubmit");
+            LOG_WARNING("Error attempting to resubmit");
+            /* We do not set esysContext->state here but inherit the most recent
+             * state of the _async function. */
             return r;
         }
         r = TSS2_ESYS_RC_TRY_AGAIN;
+        LOG_DEBUG("Resubmission initiated and returning RC_TRY_AGAIN.");
         return r;
     }
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error finish (ExecuteFinish) PolicyAuthorize");
+    /* The following is the "regular error" handling. */
+    if (r != TSS2_RC_SUCCESS && (r & TSS2_RC_LAYER_MASK) == 0) {
+        LOG_WARNING("Received TPM Error");
+        esysContext->state = _ESYS_STATE_INIT;
+        return r;
+    } else if (r != TSS2_RC_SUCCESS) {
+        LOG_ERROR("Received a non-TPM Error");
+        esysContext->state = _ESYS_STATE_INTERNALERROR;
         return r;
     }
+
     /*
      * Now the verification of the response (hmac check) and if necessary the
-     * parameter decryption have to be done
+     * parameter decryption have to be done.
      */
     r = iesys_check_response(esysContext);
-    return_if_error(r, "Error: check response");
+    return_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Error: check response");
     /*
      * After the verification of the response we call the complete function
      * to deliver the result.
      */
     r = Tss2_Sys_PolicyAuthorize_Complete(esysContext->sys);
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error finish (ExecuteFinish) PolicyAuthorize: %" PRIx32, r);
-        esysContext->state = _ESYS_STATE_ERRORRESPONSE;
-        return r;;
-    }
-    esysContext->state = _ESYS_STATE_FINISHED;
+    return_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Received error from SAPI"
+                        " unmarshalling" );
+    esysContext->state = _ESYS_STATE_INIT;
+    LOG_DEBUG("context=%p",
+              esysContext);
 
-    return r;
+    return TSS2_RC_SUCCESS;
 }
diff --git a/src/tss2-esys/api/Esys_PolicyAuthorizeNV.c b/src/tss2-esys/api/Esys_PolicyAuthorizeNV.c
index 60582c2..4268c67 100644
--- a/src/tss2-esys/api/Esys_PolicyAuthorizeNV.c
+++ b/src/tss2-esys/api/Esys_PolicyAuthorizeNV.c
@@ -155,6 +155,7 @@
     RSRC_NODE_T *nvIndexNode;
     RSRC_NODE_T *policySessionNode;
 
+    /* Check context, sequence correctness and set state to error for now */
     if (esysContext == NULL) {
         LOG_ERROR("esyscontext is NULL.");
         return TSS2_ESYS_RC_BAD_REFERENCE;
@@ -162,45 +163,46 @@
     r = iesys_check_sequence_async(esysContext);
     if (r != TSS2_RC_SUCCESS)
         return r;
-    r = check_session_feasability(shandle1, shandle2, shandle3, 1);
-    return_if_error(r, "Check session usage");
+    esysContext->state = _ESYS_STATE_INTERNALERROR;
 
+    /* Check and store input parameters */
+    r = check_session_feasability(shandle1, shandle2, shandle3, 1);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Check session usage");
     store_input_parameters(esysContext, authHandle, nvIndex, policySession);
+
+    /* Retrieve the metadata objects for provided handles */
     r = esys_GetResourceObject(esysContext, authHandle, &authHandleNode);
-    if (r != TPM2_RC_SUCCESS)
-        return r;
+    return_state_if_error(r, _ESYS_STATE_INIT, "authHandle unknown.");
     r = esys_GetResourceObject(esysContext, nvIndex, &nvIndexNode);
-    if (r != TPM2_RC_SUCCESS)
-        return r;
+    return_state_if_error(r, _ESYS_STATE_INIT, "nvIndex unknown.");
     r = esys_GetResourceObject(esysContext, policySession, &policySessionNode);
-    if (r != TPM2_RC_SUCCESS)
-        return r;
+    return_state_if_error(r, _ESYS_STATE_INIT, "policySession unknown.");
+
+    /* Initial invocation of SAPI to prepare the command buffer with parameters */
     r = Tss2_Sys_PolicyAuthorizeNV_Prepare(esysContext->sys,
                 (authHandleNode == NULL) ? TPM2_RH_NULL : authHandleNode->rsrc.handle,
                 (nvIndexNode == NULL) ? TPM2_RH_NULL : nvIndexNode->rsrc.handle,
                 (policySessionNode == NULL) ? TPM2_RH_NULL : policySessionNode->rsrc.handle);
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error async PolicyAuthorizeNV");
-        return r;
-    }
-    r = init_session_tab(esysContext, shandle1, shandle2, shandle3);
-    return_if_error(r, "Initialize session resources");
+    return_state_if_error(r, _ESYS_STATE_INIT, "SAPI Prepare returned error.");
 
+    /* Calculate the cpHash Values */
+    r = init_session_tab(esysContext, shandle1, shandle2, shandle3);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Initialize session resources");
     iesys_compute_session_value(esysContext->session_tab[0],
                 &authHandleNode->rsrc.name, &authHandleNode->auth);
     iesys_compute_session_value(esysContext->session_tab[1], NULL, NULL);
     iesys_compute_session_value(esysContext->session_tab[2], NULL, NULL);
-    r = iesys_gen_auths(esysContext, authHandleNode, nvIndexNode, policySessionNode, &auths);
-    return_if_error(r, "Error in computation of auth values");
 
+    /* Generate the auth values and set them in the SAPI command buffer */
+    r = iesys_gen_auths(esysContext, authHandleNode, nvIndexNode, policySessionNode, &auths);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Error in computation of auth values");
     esysContext->authsCount = auths.count;
     r = Tss2_Sys_SetCmdAuths(esysContext->sys, &auths);
-    if (r != TSS2_RC_SUCCESS) {
-        return r;
-    }
+    return_state_if_error(r, _ESYS_STATE_INIT, "SAPI error on SetCmdAuths");
 
+    /* Trigger execution and finish the async invocation */
     r = Tss2_Sys_ExecuteAsync(esysContext->sys);
-    return_if_error(r, "Finish (Execute Async)");
+    return_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Finish (Execute Async)");
 
     esysContext->state = _ESYS_STATE_SENT;
 
@@ -224,26 +226,34 @@
     ESYS_CONTEXT *esysContext)
 {
     LOG_TRACE("complete");
+    TSS2_RC r;
     if (esysContext == NULL) {
         LOG_ERROR("esyscontext is NULL.");
         return TSS2_ESYS_RC_BAD_REFERENCE;
     }
+
+    /* Check for correct sequence and set sequence to irregular for now */
     if (esysContext->state != _ESYS_STATE_SENT) {
         LOG_ERROR("Esys called in bad sequence.");
         return TSS2_ESYS_RC_BAD_SEQUENCE;
     }
-    TSS2_RC r;
+    esysContext->state = _ESYS_STATE_INTERNALERROR;
+
+    /*Receive the TPM response and handle resubmissions if necessary. */
     r = Tss2_Sys_ExecuteFinish(esysContext->sys, esysContext->timeout);
     if ((r & ~TSS2_RC_LAYER_MASK) == TSS2_BASE_RC_TRY_AGAIN) {
         LOG_DEBUG("A layer below returned TRY_AGAIN: %" PRIx32, r);
+        esysContext->state = _ESYS_STATE_SENT;
         return r;
     }
+    /* This block handle the resubmission of TPM commands given a certain set of
+     * TPM response codes. */
     if (r == TPM2_RC_RETRY || r == TPM2_RC_TESTING || r == TPM2_RC_YIELDED) {
         LOG_DEBUG("TPM returned RETRY, TESTING or YIELDED, which triggers a "
             "resubmission: %" PRIx32, r);
         if (esysContext->submissionCount >= _ESYS_MAX_SUBMISSIONS) {
-            LOG_WARNING("Maximum number of resubmissions has been reached.");
-            esysContext->state = _ESYS_STATE_ERRORRESPONSE;
+            LOG_WARNING("Maximum number of (re)submissions has been reached.");
+            esysContext->state = _ESYS_STATE_INIT;
             return r;
         }
         esysContext->state = _ESYS_STATE_RESUBMISSION;
@@ -255,33 +265,42 @@
                 esysContext->session_type[1],
                 esysContext->session_type[2]);
         if (r != TSS2_RC_SUCCESS) {
-            LOG_ERROR("Error attempting to resubmit");
+            LOG_WARNING("Error attempting to resubmit");
+            /* We do not set esysContext->state here but inherit the most recent
+             * state of the _async function. */
             return r;
         }
         r = TSS2_ESYS_RC_TRY_AGAIN;
+        LOG_DEBUG("Resubmission initiated and returning RC_TRY_AGAIN.");
         return r;
     }
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error finish (ExecuteFinish) PolicyAuthorizeNV");
+    /* The following is the "regular error" handling. */
+    if (r != TSS2_RC_SUCCESS && (r & TSS2_RC_LAYER_MASK) == 0) {
+        LOG_WARNING("Received TPM Error");
+        esysContext->state = _ESYS_STATE_INIT;
+        return r;
+    } else if (r != TSS2_RC_SUCCESS) {
+        LOG_ERROR("Received a non-TPM Error");
+        esysContext->state = _ESYS_STATE_INTERNALERROR;
         return r;
     }
+
     /*
      * Now the verification of the response (hmac check) and if necessary the
-     * parameter decryption have to be done
+     * parameter decryption have to be done.
      */
     r = iesys_check_response(esysContext);
-    return_if_error(r, "Error: check response");
+    return_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Error: check response");
     /*
      * After the verification of the response we call the complete function
      * to deliver the result.
      */
     r = Tss2_Sys_PolicyAuthorizeNV_Complete(esysContext->sys);
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error finish (ExecuteFinish) PolicyAuthorizeNV: %" PRIx32, r);
-        esysContext->state = _ESYS_STATE_ERRORRESPONSE;
-        return r;;
-    }
-    esysContext->state = _ESYS_STATE_FINISHED;
+    return_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Received error from SAPI"
+                        " unmarshalling" );
+    esysContext->state = _ESYS_STATE_INIT;
+    LOG_DEBUG("context=%p",
+              esysContext);
 
-    return r;
+    return TSS2_RC_SUCCESS;
 }
diff --git a/src/tss2-esys/api/Esys_PolicyCommandCode.c b/src/tss2-esys/api/Esys_PolicyCommandCode.c
index 0f796fb..7ce05cc 100644
--- a/src/tss2-esys/api/Esys_PolicyCommandCode.c
+++ b/src/tss2-esys/api/Esys_PolicyCommandCode.c
@@ -142,6 +142,7 @@
     TSS2L_SYS_AUTH_COMMAND auths;
     RSRC_NODE_T *policySessionNode;
 
+    /* Check context, sequence correctness and set state to error for now */
     if (esysContext == NULL) {
         LOG_ERROR("esyscontext is NULL.");
         return TSS2_ESYS_RC_BAD_REFERENCE;
@@ -149,36 +150,41 @@
     r = iesys_check_sequence_async(esysContext);
     if (r != TSS2_RC_SUCCESS)
         return r;
-    r = check_session_feasability(shandle1, shandle2, shandle3, 0);
-    return_if_error(r, "Check session usage");
+    esysContext->state = _ESYS_STATE_INTERNALERROR;
 
-    store_input_parameters(esysContext, policySession, code);
+    /* Check and store input parameters */
+    r = check_session_feasability(shandle1, shandle2, shandle3, 0);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Check session usage");
+    store_input_parameters(esysContext, policySession,
+                code);
+
+    /* Retrieve the metadata objects for provided handles */
     r = esys_GetResourceObject(esysContext, policySession, &policySessionNode);
-    if (r != TPM2_RC_SUCCESS)
-        return r;
+    return_state_if_error(r, _ESYS_STATE_INIT, "policySession unknown.");
+
+    /* Initial invocation of SAPI to prepare the command buffer with parameters */
     r = Tss2_Sys_PolicyCommandCode_Prepare(esysContext->sys,
                 (policySessionNode == NULL) ? TPM2_RH_NULL : policySessionNode->rsrc.handle,
                 code);
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error async PolicyCommandCode");
-        return r;
-    }
-    r = init_session_tab(esysContext, shandle1, shandle2, shandle3);
-    return_if_error(r, "Initialize session resources");
+    return_state_if_error(r, _ESYS_STATE_INIT, "SAPI Prepare returned error.");
 
+    /* Calculate the cpHash Values */
+    r = init_session_tab(esysContext, shandle1, shandle2, shandle3);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Initialize session resources");
     iesys_compute_session_value(esysContext->session_tab[0], NULL, NULL);
     iesys_compute_session_value(esysContext->session_tab[1], NULL, NULL);
-    r = iesys_gen_auths(esysContext, policySessionNode, NULL, NULL, &auths);
-    return_if_error(r, "Error in computation of auth values");
+    iesys_compute_session_value(esysContext->session_tab[2], NULL, NULL);
 
+    /* Generate the auth values and set them in the SAPI command buffer */
+    r = iesys_gen_auths(esysContext, policySessionNode, NULL, NULL, &auths);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Error in computation of auth values");
     esysContext->authsCount = auths.count;
     r = Tss2_Sys_SetCmdAuths(esysContext->sys, &auths);
-    if (r != TSS2_RC_SUCCESS) {
-        return r;
-    }
+    return_state_if_error(r, _ESYS_STATE_INIT, "SAPI error on SetCmdAuths");
 
+    /* Trigger execution and finish the async invocation */
     r = Tss2_Sys_ExecuteAsync(esysContext->sys);
-    return_if_error(r, "Finish (Execute Async)");
+    return_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Finish (Execute Async)");
 
     esysContext->state = _ESYS_STATE_SENT;
 
@@ -202,26 +208,34 @@
     ESYS_CONTEXT *esysContext)
 {
     LOG_TRACE("complete");
+    TSS2_RC r;
     if (esysContext == NULL) {
         LOG_ERROR("esyscontext is NULL.");
         return TSS2_ESYS_RC_BAD_REFERENCE;
     }
+
+    /* Check for correct sequence and set sequence to irregular for now */
     if (esysContext->state != _ESYS_STATE_SENT) {
         LOG_ERROR("Esys called in bad sequence.");
         return TSS2_ESYS_RC_BAD_SEQUENCE;
     }
-    TSS2_RC r;
+    esysContext->state = _ESYS_STATE_INTERNALERROR;
+
+    /*Receive the TPM response and handle resubmissions if necessary. */
     r = Tss2_Sys_ExecuteFinish(esysContext->sys, esysContext->timeout);
     if ((r & ~TSS2_RC_LAYER_MASK) == TSS2_BASE_RC_TRY_AGAIN) {
         LOG_DEBUG("A layer below returned TRY_AGAIN: %" PRIx32, r);
+        esysContext->state = _ESYS_STATE_SENT;
         return r;
     }
+    /* This block handle the resubmission of TPM commands given a certain set of
+     * TPM response codes. */
     if (r == TPM2_RC_RETRY || r == TPM2_RC_TESTING || r == TPM2_RC_YIELDED) {
         LOG_DEBUG("TPM returned RETRY, TESTING or YIELDED, which triggers a "
             "resubmission: %" PRIx32, r);
         if (esysContext->submissionCount >= _ESYS_MAX_SUBMISSIONS) {
-            LOG_WARNING("Maximum number of resubmissions has been reached.");
-            esysContext->state = _ESYS_STATE_ERRORRESPONSE;
+            LOG_WARNING("Maximum number of (re)submissions has been reached.");
+            esysContext->state = _ESYS_STATE_INIT;
             return r;
         }
         esysContext->state = _ESYS_STATE_RESUBMISSION;
@@ -232,33 +246,42 @@
                 esysContext->session_type[2],
                 esysContext->in.PolicyCommandCode.code);
         if (r != TSS2_RC_SUCCESS) {
-            LOG_ERROR("Error attempting to resubmit");
+            LOG_WARNING("Error attempting to resubmit");
+            /* We do not set esysContext->state here but inherit the most recent
+             * state of the _async function. */
             return r;
         }
         r = TSS2_ESYS_RC_TRY_AGAIN;
+        LOG_DEBUG("Resubmission initiated and returning RC_TRY_AGAIN.");
         return r;
     }
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error finish (ExecuteFinish) PolicyCommandCode");
+    /* The following is the "regular error" handling. */
+    if (r != TSS2_RC_SUCCESS && (r & TSS2_RC_LAYER_MASK) == 0) {
+        LOG_WARNING("Received TPM Error");
+        esysContext->state = _ESYS_STATE_INIT;
+        return r;
+    } else if (r != TSS2_RC_SUCCESS) {
+        LOG_ERROR("Received a non-TPM Error");
+        esysContext->state = _ESYS_STATE_INTERNALERROR;
         return r;
     }
+
     /*
      * Now the verification of the response (hmac check) and if necessary the
-     * parameter decryption have to be done
+     * parameter decryption have to be done.
      */
     r = iesys_check_response(esysContext);
-    return_if_error(r, "Error: check response");
+    return_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Error: check response");
     /*
      * After the verification of the response we call the complete function
      * to deliver the result.
      */
     r = Tss2_Sys_PolicyCommandCode_Complete(esysContext->sys);
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error finish (ExecuteFinish) PolicyCommandCode: %" PRIx32, r);
-        esysContext->state = _ESYS_STATE_ERRORRESPONSE;
-        return r;;
-    }
-    esysContext->state = _ESYS_STATE_FINISHED;
+    return_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Received error from SAPI"
+                        " unmarshalling" );
+    esysContext->state = _ESYS_STATE_INIT;
+    LOG_DEBUG("context=%p",
+              esysContext);
 
-    return r;
+    return TSS2_RC_SUCCESS;
 }
diff --git a/src/tss2-esys/api/Esys_PolicyCounterTimer.c b/src/tss2-esys/api/Esys_PolicyCounterTimer.c
index a24db7d..8d0a5a9 100644
--- a/src/tss2-esys/api/Esys_PolicyCounterTimer.c
+++ b/src/tss2-esys/api/Esys_PolicyCounterTimer.c
@@ -162,6 +162,7 @@
     TSS2L_SYS_AUTH_COMMAND auths;
     RSRC_NODE_T *policySessionNode;
 
+    /* Check context, sequence correctness and set state to error for now */
     if (esysContext == NULL) {
         LOG_ERROR("esyscontext is NULL.");
         return TSS2_ESYS_RC_BAD_REFERENCE;
@@ -169,42 +170,45 @@
     r = iesys_check_sequence_async(esysContext);
     if (r != TSS2_RC_SUCCESS)
         return r;
-    r = check_session_feasability(shandle1, shandle2, shandle3, 0);
-    return_if_error(r, "Check session usage");
+    esysContext->state = _ESYS_STATE_INTERNALERROR;
 
+    /* Check and store input parameters */
+    r = check_session_feasability(shandle1, shandle2, shandle3, 0);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Check session usage");
     store_input_parameters(esysContext, policySession,
                 operandB,
                 offset,
                 operation);
+
+    /* Retrieve the metadata objects for provided handles */
     r = esys_GetResourceObject(esysContext, policySession, &policySessionNode);
-    if (r != TPM2_RC_SUCCESS)
-        return r;
+    return_state_if_error(r, _ESYS_STATE_INIT, "policySession unknown.");
+
+    /* Initial invocation of SAPI to prepare the command buffer with parameters */
     r = Tss2_Sys_PolicyCounterTimer_Prepare(esysContext->sys,
                 (policySessionNode == NULL) ? TPM2_RH_NULL : policySessionNode->rsrc.handle,
                 operandB,
                 offset,
                 operation);
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error async PolicyCounterTimer");
-        return r;
-    }
-    r = init_session_tab(esysContext, shandle1, shandle2, shandle3);
-    return_if_error(r, "Initialize session resources");
+    return_state_if_error(r, _ESYS_STATE_INIT, "SAPI Prepare returned error.");
 
+    /* Calculate the cpHash Values */
+    r = init_session_tab(esysContext, shandle1, shandle2, shandle3);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Initialize session resources");
     iesys_compute_session_value(esysContext->session_tab[0], NULL, NULL);
     iesys_compute_session_value(esysContext->session_tab[1], NULL, NULL);
     iesys_compute_session_value(esysContext->session_tab[2], NULL, NULL);
-    r = iesys_gen_auths(esysContext, policySessionNode, NULL, NULL, &auths);
-    return_if_error(r, "Error in computation of auth values");
 
+    /* Generate the auth values and set them in the SAPI command buffer */
+    r = iesys_gen_auths(esysContext, policySessionNode, NULL, NULL, &auths);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Error in computation of auth values");
     esysContext->authsCount = auths.count;
     r = Tss2_Sys_SetCmdAuths(esysContext->sys, &auths);
-    if (r != TSS2_RC_SUCCESS) {
-        return r;
-    }
+    return_state_if_error(r, _ESYS_STATE_INIT, "SAPI error on SetCmdAuths");
 
+    /* Trigger execution and finish the async invocation */
     r = Tss2_Sys_ExecuteAsync(esysContext->sys);
-    return_if_error(r, "Finish (Execute Async)");
+    return_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Finish (Execute Async)");
 
     esysContext->state = _ESYS_STATE_SENT;
 
@@ -228,26 +232,34 @@
     ESYS_CONTEXT *esysContext)
 {
     LOG_TRACE("complete");
+    TSS2_RC r;
     if (esysContext == NULL) {
         LOG_ERROR("esyscontext is NULL.");
         return TSS2_ESYS_RC_BAD_REFERENCE;
     }
+
+    /* Check for correct sequence and set sequence to irregular for now */
     if (esysContext->state != _ESYS_STATE_SENT) {
         LOG_ERROR("Esys called in bad sequence.");
         return TSS2_ESYS_RC_BAD_SEQUENCE;
     }
-    TSS2_RC r;
+    esysContext->state = _ESYS_STATE_INTERNALERROR;
+
+    /*Receive the TPM response and handle resubmissions if necessary. */
     r = Tss2_Sys_ExecuteFinish(esysContext->sys, esysContext->timeout);
     if ((r & ~TSS2_RC_LAYER_MASK) == TSS2_BASE_RC_TRY_AGAIN) {
         LOG_DEBUG("A layer below returned TRY_AGAIN: %" PRIx32, r);
+        esysContext->state = _ESYS_STATE_SENT;
         return r;
     }
+    /* This block handle the resubmission of TPM commands given a certain set of
+     * TPM response codes. */
     if (r == TPM2_RC_RETRY || r == TPM2_RC_TESTING || r == TPM2_RC_YIELDED) {
         LOG_DEBUG("TPM returned RETRY, TESTING or YIELDED, which triggers a "
             "resubmission: %" PRIx32, r);
         if (esysContext->submissionCount >= _ESYS_MAX_SUBMISSIONS) {
-            LOG_WARNING("Maximum number of resubmissions has been reached.");
-            esysContext->state = _ESYS_STATE_ERRORRESPONSE;
+            LOG_WARNING("Maximum number of (re)submissions has been reached.");
+            esysContext->state = _ESYS_STATE_INIT;
             return r;
         }
         esysContext->state = _ESYS_STATE_RESUBMISSION;
@@ -260,33 +272,42 @@
                 esysContext->in.PolicyCounterTimer.offset,
                 esysContext->in.PolicyCounterTimer.operation);
         if (r != TSS2_RC_SUCCESS) {
-            LOG_ERROR("Error attempting to resubmit");
+            LOG_WARNING("Error attempting to resubmit");
+            /* We do not set esysContext->state here but inherit the most recent
+             * state of the _async function. */
             return r;
         }
         r = TSS2_ESYS_RC_TRY_AGAIN;
+        LOG_DEBUG("Resubmission initiated and returning RC_TRY_AGAIN.");
         return r;
     }
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error finish (ExecuteFinish) PolicyCounterTimer");
+    /* The following is the "regular error" handling. */
+    if (r != TSS2_RC_SUCCESS && (r & TSS2_RC_LAYER_MASK) == 0) {
+        LOG_WARNING("Received TPM Error");
+        esysContext->state = _ESYS_STATE_INIT;
+        return r;
+    } else if (r != TSS2_RC_SUCCESS) {
+        LOG_ERROR("Received a non-TPM Error");
+        esysContext->state = _ESYS_STATE_INTERNALERROR;
         return r;
     }
+
     /*
      * Now the verification of the response (hmac check) and if necessary the
-     * parameter decryption have to be done
+     * parameter decryption have to be done.
      */
     r = iesys_check_response(esysContext);
-    return_if_error(r, "Error: check response");
+    return_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Error: check response");
     /*
      * After the verification of the response we call the complete function
      * to deliver the result.
      */
     r = Tss2_Sys_PolicyCounterTimer_Complete(esysContext->sys);
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error finish (ExecuteFinish) PolicyCounterTimer: %" PRIx32, r);
-        esysContext->state = _ESYS_STATE_ERRORRESPONSE;
-        return r;;
-    }
-    esysContext->state = _ESYS_STATE_FINISHED;
+    return_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Received error from SAPI"
+                        " unmarshalling" );
+    esysContext->state = _ESYS_STATE_INIT;
+    LOG_DEBUG("context=%p",
+              esysContext);
 
-    return r;
+    return TSS2_RC_SUCCESS;
 }
diff --git a/src/tss2-esys/api/Esys_PolicyCpHash.c b/src/tss2-esys/api/Esys_PolicyCpHash.c
index 4402f07..fa16503 100644
--- a/src/tss2-esys/api/Esys_PolicyCpHash.c
+++ b/src/tss2-esys/api/Esys_PolicyCpHash.c
@@ -145,6 +145,7 @@
     TSS2_RC r;
     TSS2L_SYS_AUTH_COMMAND auths;
 
+    /* Check context, sequence correctness and set state to error for now */
     if (esysContext == NULL) {
         LOG_ERROR("esyscontext is NULL.");
         return TSS2_ESYS_RC_BAD_REFERENCE;
@@ -152,35 +153,38 @@
     r = iesys_check_sequence_async(esysContext);
     if (r != TSS2_RC_SUCCESS)
         return r;
-    r = check_session_feasability(shandle1, shandle2, shandle3, 0);
-    return_if_error(r, "Check session usage");
+    esysContext->state = _ESYS_STATE_INTERNALERROR;
 
+    /* Check and store input parameters */
+    r = check_session_feasability(shandle1, shandle2, shandle3, 0);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Check session usage");
     store_input_parameters(esysContext,
                 policySession,
                 cpHashA);
+
+    /* Initial invocation of SAPI to prepare the command buffer with parameters */
     r = Tss2_Sys_PolicyCpHash_Prepare(esysContext->sys,
                 policySession,
                 cpHashA);
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error async PolicyCpHash");
-        return r;
-    }
-    r = init_session_tab(esysContext, shandle1, shandle2, shandle3);
-    return_if_error(r, "Initialize session resources");
+    return_state_if_error(r, _ESYS_STATE_INIT, "SAPI Prepare returned error.");
 
+    /* Calculate the cpHash Values */
+    r = init_session_tab(esysContext, shandle1, shandle2, shandle3);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Initialize session resources");
     iesys_compute_session_value(esysContext->session_tab[0], NULL, NULL);
     iesys_compute_session_value(esysContext->session_tab[1], NULL, NULL);
-    r = iesys_gen_auths(esysContext, NULL, NULL, NULL, &auths);
-    return_if_error(r, "Error in computation of auth values");
+    iesys_compute_session_value(esysContext->session_tab[2], NULL, NULL);
 
+    /* Generate the auth values and set them in the SAPI command buffer */
+    r = iesys_gen_auths(esysContext, NULL, NULL, NULL, &auths);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Error in computation of auth values");
     esysContext->authsCount = auths.count;
     r = Tss2_Sys_SetCmdAuths(esysContext->sys, &auths);
-    if (r != TSS2_RC_SUCCESS) {
-        return r;
-    }
+    return_state_if_error(r, _ESYS_STATE_INIT, "SAPI error on SetCmdAuths");
 
+    /* Trigger execution and finish the async invocation */
     r = Tss2_Sys_ExecuteAsync(esysContext->sys);
-    return_if_error(r, "Finish (Execute Async)");
+    return_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Finish (Execute Async)");
 
     esysContext->state = _ESYS_STATE_SENT;
 
@@ -204,26 +208,34 @@
     ESYS_CONTEXT *esysContext)
 {
     LOG_TRACE("complete");
+    TSS2_RC r;
     if (esysContext == NULL) {
         LOG_ERROR("esyscontext is NULL.");
         return TSS2_ESYS_RC_BAD_REFERENCE;
     }
+
+    /* Check for correct sequence and set sequence to irregular for now */
     if (esysContext->state != _ESYS_STATE_SENT) {
         LOG_ERROR("Esys called in bad sequence.");
         return TSS2_ESYS_RC_BAD_SEQUENCE;
     }
-    TSS2_RC r;
+    esysContext->state = _ESYS_STATE_INTERNALERROR;
+
+    /*Receive the TPM response and handle resubmissions if necessary. */
     r = Tss2_Sys_ExecuteFinish(esysContext->sys, esysContext->timeout);
     if ((r & ~TSS2_RC_LAYER_MASK) == TSS2_BASE_RC_TRY_AGAIN) {
         LOG_DEBUG("A layer below returned TRY_AGAIN: %" PRIx32, r);
+        esysContext->state = _ESYS_STATE_SENT;
         return r;
     }
+    /* This block handle the resubmission of TPM commands given a certain set of
+     * TPM response codes. */
     if (r == TPM2_RC_RETRY || r == TPM2_RC_TESTING || r == TPM2_RC_YIELDED) {
         LOG_DEBUG("TPM returned RETRY, TESTING or YIELDED, which triggers a "
             "resubmission: %" PRIx32, r);
         if (esysContext->submissionCount >= _ESYS_MAX_SUBMISSIONS) {
-            LOG_WARNING("Maximum number of resubmissions has been reached.");
-            esysContext->state = _ESYS_STATE_ERRORRESPONSE;
+            LOG_WARNING("Maximum number of (re)submissions has been reached.");
+            esysContext->state = _ESYS_STATE_INIT;
             return r;
         }
         esysContext->state = _ESYS_STATE_RESUBMISSION;
@@ -234,33 +246,42 @@
                 esysContext->in.PolicyCpHash.policySession,
                 esysContext->in.PolicyCpHash.cpHashA);
         if (r != TSS2_RC_SUCCESS) {
-            LOG_ERROR("Error attempting to resubmit");
+            LOG_WARNING("Error attempting to resubmit");
+            /* We do not set esysContext->state here but inherit the most recent
+             * state of the _async function. */
             return r;
         }
         r = TSS2_ESYS_RC_TRY_AGAIN;
+        LOG_DEBUG("Resubmission initiated and returning RC_TRY_AGAIN.");
         return r;
     }
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error finish (ExecuteFinish) PolicyCpHash");
+    /* The following is the "regular error" handling. */
+    if (r != TSS2_RC_SUCCESS && (r & TSS2_RC_LAYER_MASK) == 0) {
+        LOG_WARNING("Received TPM Error");
+        esysContext->state = _ESYS_STATE_INIT;
+        return r;
+    } else if (r != TSS2_RC_SUCCESS) {
+        LOG_ERROR("Received a non-TPM Error");
+        esysContext->state = _ESYS_STATE_INTERNALERROR;
         return r;
     }
+
     /*
      * Now the verification of the response (hmac check) and if necessary the
-     * parameter decryption have to be done
+     * parameter decryption have to be done.
      */
     r = iesys_check_response(esysContext);
-    return_if_error(r, "Error: check response");
+    return_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Error: check response");
     /*
      * After the verification of the response we call the complete function
      * to deliver the result.
      */
     r = Tss2_Sys_PolicyCpHash_Complete(esysContext->sys);
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error finish (ExecuteFinish) PolicyCpHash: %" PRIx32, r);
-        esysContext->state = _ESYS_STATE_ERRORRESPONSE;
-        return r;;
-    }
-    esysContext->state = _ESYS_STATE_FINISHED;
+    return_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Received error from SAPI"
+                        " unmarshalling" );
+    esysContext->state = _ESYS_STATE_INIT;
+    LOG_DEBUG("context=%p",
+              esysContext);
 
-    return r;
+    return TSS2_RC_SUCCESS;
 }
diff --git a/src/tss2-esys/api/Esys_PolicyDuplicationSelect.c b/src/tss2-esys/api/Esys_PolicyDuplicationSelect.c
index c6759d8..3e44222 100644
--- a/src/tss2-esys/api/Esys_PolicyDuplicationSelect.c
+++ b/src/tss2-esys/api/Esys_PolicyDuplicationSelect.c
@@ -165,6 +165,7 @@
     TSS2_RC r;
     TSS2L_SYS_AUTH_COMMAND auths;
 
+    /* Check context, sequence correctness and set state to error for now */
     if (esysContext == NULL) {
         LOG_ERROR("esyscontext is NULL.");
         return TSS2_ESYS_RC_BAD_REFERENCE;
@@ -172,40 +173,42 @@
     r = iesys_check_sequence_async(esysContext);
     if (r != TSS2_RC_SUCCESS)
         return r;
-    r = check_session_feasability(shandle1, shandle2, shandle3, 0);
-    return_if_error(r, "Check session usage");
+    esysContext->state = _ESYS_STATE_INTERNALERROR;
 
+    /* Check and store input parameters */
+    r = check_session_feasability(shandle1, shandle2, shandle3, 0);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Check session usage");
     store_input_parameters(esysContext,
                 policySession,
                 objectName,
                 newParentName,
                 includeObject);
+
+    /* Initial invocation of SAPI to prepare the command buffer with parameters */
     r = Tss2_Sys_PolicyDuplicationSelect_Prepare(esysContext->sys,
                 policySession,
                 objectName,
                 newParentName,
                 includeObject);
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error async PolicyDuplicationSelect");
-        return r;
-    }
-    r = init_session_tab(esysContext, shandle1, shandle2, shandle3);
-    return_if_error(r, "Initialize session resources");
+    return_state_if_error(r, _ESYS_STATE_INIT, "SAPI Prepare returned error.");
 
+    /* Calculate the cpHash Values */
+    r = init_session_tab(esysContext, shandle1, shandle2, shandle3);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Initialize session resources");
     iesys_compute_session_value(esysContext->session_tab[0], NULL, NULL);
     iesys_compute_session_value(esysContext->session_tab[1], NULL, NULL);
     iesys_compute_session_value(esysContext->session_tab[2], NULL, NULL);
-    r = iesys_gen_auths(esysContext, NULL, NULL, NULL, &auths);
-    return_if_error(r, "Error in computation of auth values");
 
+    /* Generate the auth values and set them in the SAPI command buffer */
+    r = iesys_gen_auths(esysContext, NULL, NULL, NULL, &auths);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Error in computation of auth values");
     esysContext->authsCount = auths.count;
     r = Tss2_Sys_SetCmdAuths(esysContext->sys, &auths);
-    if (r != TSS2_RC_SUCCESS) {
-        return r;
-    }
+    return_state_if_error(r, _ESYS_STATE_INIT, "SAPI error on SetCmdAuths");
 
+    /* Trigger execution and finish the async invocation */
     r = Tss2_Sys_ExecuteAsync(esysContext->sys);
-    return_if_error(r, "Finish (Execute Async)");
+    return_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Finish (Execute Async)");
 
     esysContext->state = _ESYS_STATE_SENT;
 
@@ -229,26 +232,34 @@
     ESYS_CONTEXT *esysContext)
 {
     LOG_TRACE("complete");
+    TSS2_RC r;
     if (esysContext == NULL) {
         LOG_ERROR("esyscontext is NULL.");
         return TSS2_ESYS_RC_BAD_REFERENCE;
     }
+
+    /* Check for correct sequence and set sequence to irregular for now */
     if (esysContext->state != _ESYS_STATE_SENT) {
         LOG_ERROR("Esys called in bad sequence.");
         return TSS2_ESYS_RC_BAD_SEQUENCE;
     }
-    TSS2_RC r;
+    esysContext->state = _ESYS_STATE_INTERNALERROR;
+
+    /*Receive the TPM response and handle resubmissions if necessary. */
     r = Tss2_Sys_ExecuteFinish(esysContext->sys, esysContext->timeout);
     if ((r & ~TSS2_RC_LAYER_MASK) == TSS2_BASE_RC_TRY_AGAIN) {
         LOG_DEBUG("A layer below returned TRY_AGAIN: %" PRIx32, r);
+        esysContext->state = _ESYS_STATE_SENT;
         return r;
     }
+    /* This block handle the resubmission of TPM commands given a certain set of
+     * TPM response codes. */
     if (r == TPM2_RC_RETRY || r == TPM2_RC_TESTING || r == TPM2_RC_YIELDED) {
         LOG_DEBUG("TPM returned RETRY, TESTING or YIELDED, which triggers a "
             "resubmission: %" PRIx32, r);
         if (esysContext->submissionCount >= _ESYS_MAX_SUBMISSIONS) {
-            LOG_WARNING("Maximum number of resubmissions has been reached.");
-            esysContext->state = _ESYS_STATE_ERRORRESPONSE;
+            LOG_WARNING("Maximum number of (re)submissions has been reached.");
+            esysContext->state = _ESYS_STATE_INIT;
             return r;
         }
         esysContext->state = _ESYS_STATE_RESUBMISSION;
@@ -261,33 +272,42 @@
                 esysContext->in.PolicyDuplicationSelect.newParentName,
                 esysContext->in.PolicyDuplicationSelect.includeObject);
         if (r != TSS2_RC_SUCCESS) {
-            LOG_ERROR("Error attempting to resubmit");
+            LOG_WARNING("Error attempting to resubmit");
+            /* We do not set esysContext->state here but inherit the most recent
+             * state of the _async function. */
             return r;
         }
         r = TSS2_ESYS_RC_TRY_AGAIN;
+        LOG_DEBUG("Resubmission initiated and returning RC_TRY_AGAIN.");
         return r;
     }
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error finish (ExecuteFinish) PolicyDuplicationSelect");
+    /* The following is the "regular error" handling. */
+    if (r != TSS2_RC_SUCCESS && (r & TSS2_RC_LAYER_MASK) == 0) {
+        LOG_WARNING("Received TPM Error");
+        esysContext->state = _ESYS_STATE_INIT;
+        return r;
+    } else if (r != TSS2_RC_SUCCESS) {
+        LOG_ERROR("Received a non-TPM Error");
+        esysContext->state = _ESYS_STATE_INTERNALERROR;
         return r;
     }
+
     /*
      * Now the verification of the response (hmac check) and if necessary the
-     * parameter decryption have to be done
+     * parameter decryption have to be done.
      */
     r = iesys_check_response(esysContext);
-    return_if_error(r, "Error: check response");
+    return_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Error: check response");
     /*
      * After the verification of the response we call the complete function
      * to deliver the result.
      */
     r = Tss2_Sys_PolicyDuplicationSelect_Complete(esysContext->sys);
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error finish (ExecuteFinish) PolicyDuplicationSelect: %" PRIx32, r);
-        esysContext->state = _ESYS_STATE_ERRORRESPONSE;
-        return r;;
-    }
-    esysContext->state = _ESYS_STATE_FINISHED;
+    return_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Received error from SAPI"
+                        " unmarshalling" );
+    esysContext->state = _ESYS_STATE_INIT;
+    LOG_DEBUG("context=%p",
+              esysContext);
 
-    return r;
+    return TSS2_RC_SUCCESS;
 }
diff --git a/src/tss2-esys/api/Esys_PolicyGetDigest.c b/src/tss2-esys/api/Esys_PolicyGetDigest.c
index 92a68fa..e6ca83a 100644
--- a/src/tss2-esys/api/Esys_PolicyGetDigest.c
+++ b/src/tss2-esys/api/Esys_PolicyGetDigest.c
@@ -139,6 +139,7 @@
     TSS2L_SYS_AUTH_COMMAND auths;
     RSRC_NODE_T *policySessionNode;
 
+    /* Check context, sequence correctness and set state to error for now */
     if (esysContext == NULL) {
         LOG_ERROR("esyscontext is NULL.");
         return TSS2_ESYS_RC_BAD_REFERENCE;
@@ -146,34 +147,39 @@
     r = iesys_check_sequence_async(esysContext);
     if (r != TSS2_RC_SUCCESS)
         return r;
-    r = check_session_feasability(shandle1, shandle2, shandle3, 0);
-    return_if_error(r, "Check session usage");
+    esysContext->state = _ESYS_STATE_INTERNALERROR;
 
+    /* Check and store input parameters */
+    r = check_session_feasability(shandle1, shandle2, shandle3, 0);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Check session usage");
     store_input_parameters(esysContext, policySession);
+
+    /* Retrieve the metadata objects for provided handles */
     r = esys_GetResourceObject(esysContext, policySession, &policySessionNode);
-    if (r != TPM2_RC_SUCCESS)
-        return r;
+    return_state_if_error(r, _ESYS_STATE_INIT, "policySession unknown.");
+
+    /* Initial invocation of SAPI to prepare the command buffer with parameters */
     r = Tss2_Sys_PolicyGetDigest_Prepare(esysContext->sys,
                 (policySessionNode == NULL) ? TPM2_RH_NULL : policySessionNode->rsrc.handle);
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error async PolicyGetDigest");
-        return r;
-    }
+    return_state_if_error(r, _ESYS_STATE_INIT, "SAPI Prepare returned error.");
+
+    /* Calculate the cpHash Values */
     r = init_session_tab(esysContext, shandle1, shandle2, shandle3);
-    return_if_error(r, "Initialize session resources");
-
+    return_state_if_error(r, _ESYS_STATE_INIT, "Initialize session resources");
     iesys_compute_session_value(esysContext->session_tab[0], NULL, NULL);
-    r = iesys_gen_auths(esysContext, policySessionNode, NULL, NULL, &auths);
-    return_if_error(r, "Error in computation of auth values");
+    iesys_compute_session_value(esysContext->session_tab[1], NULL, NULL);
+    iesys_compute_session_value(esysContext->session_tab[2], NULL, NULL);
 
+    /* Generate the auth values and set them in the SAPI command buffer */
+    r = iesys_gen_auths(esysContext, policySessionNode, NULL, NULL, &auths);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Error in computation of auth values");
     esysContext->authsCount = auths.count;
     r = Tss2_Sys_SetCmdAuths(esysContext->sys, &auths);
-    if (r != TSS2_RC_SUCCESS) {
-        return r;
-    }
+    return_state_if_error(r, _ESYS_STATE_INIT, "SAPI error on SetCmdAuths");
 
+    /* Trigger execution and finish the async invocation */
     r = Tss2_Sys_ExecuteAsync(esysContext->sys);
-    return_if_error(r, "Finish (Execute Async)");
+    return_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Finish (Execute Async)");
 
     esysContext->state = _ESYS_STATE_SENT;
 
@@ -200,32 +206,42 @@
     TPM2B_DIGEST **policyDigest)
 {
     LOG_TRACE("complete");
+    TSS2_RC r;
     if (esysContext == NULL) {
         LOG_ERROR("esyscontext is NULL.");
         return TSS2_ESYS_RC_BAD_REFERENCE;
     }
+
+    /* Check for correct sequence and set sequence to irregular for now */
     if (esysContext->state != _ESYS_STATE_SENT) {
         LOG_ERROR("Esys called in bad sequence.");
         return TSS2_ESYS_RC_BAD_SEQUENCE;
     }
-    TSS2_RC r;
+    esysContext->state = _ESYS_STATE_INTERNALERROR;
+
+    /* Allocate memory for response parameters */
     if (policyDigest != NULL) {
         *policyDigest = calloc(sizeof(TPM2B_DIGEST), 1);
         if (*policyDigest == NULL) {
             return_error(TSS2_ESYS_RC_MEMORY, "Out of memory");
         }
     }
+
+    /*Receive the TPM response and handle resubmissions if necessary. */
     r = Tss2_Sys_ExecuteFinish(esysContext->sys, esysContext->timeout);
     if ((r & ~TSS2_RC_LAYER_MASK) == TSS2_BASE_RC_TRY_AGAIN) {
         LOG_DEBUG("A layer below returned TRY_AGAIN: %" PRIx32, r);
+        esysContext->state = _ESYS_STATE_SENT;
         goto error_cleanup;
     }
+    /* This block handle the resubmission of TPM commands given a certain set of
+     * TPM response codes. */
     if (r == TPM2_RC_RETRY || r == TPM2_RC_TESTING || r == TPM2_RC_YIELDED) {
         LOG_DEBUG("TPM returned RETRY, TESTING or YIELDED, which triggers a "
             "resubmission: %" PRIx32, r);
         if (esysContext->submissionCount >= _ESYS_MAX_SUBMISSIONS) {
-            LOG_WARNING("Maximum number of resubmissions has been reached.");
-            esysContext->state = _ESYS_STATE_ERRORRESPONSE;
+            LOG_WARNING("Maximum number of (re)submissions has been reached.");
+            esysContext->state = _ESYS_STATE_INIT;
             goto error_cleanup;
         }
         esysContext->state = _ESYS_STATE_RESUBMISSION;
@@ -235,22 +251,32 @@
                 esysContext->session_type[1],
                 esysContext->session_type[2]);
         if (r != TSS2_RC_SUCCESS) {
-            LOG_ERROR("Error attempting to resubmit");
+            LOG_WARNING("Error attempting to resubmit");
+            /* We do not set esysContext->state here but inherit the most recent
+             * state of the _async function. */
             goto error_cleanup;
         }
         r = TSS2_ESYS_RC_TRY_AGAIN;
+        LOG_DEBUG("Resubmission initiated and returning RC_TRY_AGAIN.");
         goto error_cleanup;
     }
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error finish (ExecuteFinish) PolicyGetDigest");
+    /* The following is the "regular error" handling. */
+    if (r != TSS2_RC_SUCCESS && (r & TSS2_RC_LAYER_MASK) == 0) {
+        LOG_WARNING("Received TPM Error");
+        esysContext->state = _ESYS_STATE_INIT;
+        goto error_cleanup;
+    } else if (r != TSS2_RC_SUCCESS) {
+        LOG_ERROR("Received a non-TPM Error");
+        esysContext->state = _ESYS_STATE_INTERNALERROR;
         goto error_cleanup;
     }
+
     /*
      * Now the verification of the response (hmac check) and if necessary the
-     * parameter decryption have to be done
+     * parameter decryption have to be done.
      */
     r = iesys_check_response(esysContext);
-    goto_if_error(r, "Error: check response",
+    goto_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Error: check response",
                       error_cleanup);
     /*
      * After the verification of the response we call the complete function
@@ -258,17 +284,17 @@
      */
     r = Tss2_Sys_PolicyGetDigest_Complete(esysContext->sys,
                 (policyDigest != NULL) ? *policyDigest : NULL);
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error finish (ExecuteFinish) PolicyGetDigest: %" PRIx32, r);
-        esysContext->state = _ESYS_STATE_ERRORRESPONSE;
-        goto error_cleanup;;
-    }
-    esysContext->state = _ESYS_STATE_FINISHED;
+    goto_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Received error from SAPI"
+                        " unmarshalling" ,error_cleanup);
+    esysContext->state = _ESYS_STATE_INIT;
+    LOG_DEBUG("context=%p, policyDigest=%p",
+              esysContext, policyDigest);
 
-    return r;
+    return TSS2_RC_SUCCESS;
 
 error_cleanup:
     if (policyDigest != NULL)
         SAFE_FREE(*policyDigest);
+
     return r;
 }
diff --git a/src/tss2-esys/api/Esys_PolicyLocality.c b/src/tss2-esys/api/Esys_PolicyLocality.c
index d599dd0..8515fa0 100644
--- a/src/tss2-esys/api/Esys_PolicyLocality.c
+++ b/src/tss2-esys/api/Esys_PolicyLocality.c
@@ -139,6 +139,7 @@
     TSS2_RC r;
     TSS2L_SYS_AUTH_COMMAND auths;
 
+    /* Check context, sequence correctness and set state to error for now */
     if (esysContext == NULL) {
         LOG_ERROR("esyscontext is NULL.");
         return TSS2_ESYS_RC_BAD_REFERENCE;
@@ -146,35 +147,38 @@
     r = iesys_check_sequence_async(esysContext);
     if (r != TSS2_RC_SUCCESS)
         return r;
-    r = check_session_feasability(shandle1, shandle2, shandle3, 0);
-    return_if_error(r, "Check session usage");
+    esysContext->state = _ESYS_STATE_INTERNALERROR;
 
+    /* Check and store input parameters */
+    r = check_session_feasability(shandle1, shandle2, shandle3, 0);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Check session usage");
     store_input_parameters(esysContext,
                 policySession,
                 locality);
+
+    /* Initial invocation of SAPI to prepare the command buffer with parameters */
     r = Tss2_Sys_PolicyLocality_Prepare(esysContext->sys,
                 policySession,
                 locality);
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error async PolicyLocality");
-        return r;
-    }
-    r = init_session_tab(esysContext, shandle1, shandle2, shandle3);
-    return_if_error(r, "Initialize session resources");
+    return_state_if_error(r, _ESYS_STATE_INIT, "SAPI Prepare returned error.");
 
+    /* Calculate the cpHash Values */
+    r = init_session_tab(esysContext, shandle1, shandle2, shandle3);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Initialize session resources");
     iesys_compute_session_value(esysContext->session_tab[0], NULL, NULL);
     iesys_compute_session_value(esysContext->session_tab[1], NULL, NULL);
-    r = iesys_gen_auths(esysContext, NULL, NULL, NULL, &auths);
-    return_if_error(r, "Error in computation of auth values");
+    iesys_compute_session_value(esysContext->session_tab[2], NULL, NULL);
 
+    /* Generate the auth values and set them in the SAPI command buffer */
+    r = iesys_gen_auths(esysContext, NULL, NULL, NULL, &auths);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Error in computation of auth values");
     esysContext->authsCount = auths.count;
     r = Tss2_Sys_SetCmdAuths(esysContext->sys, &auths);
-    if (r != TSS2_RC_SUCCESS) {
-        return r;
-    }
+    return_state_if_error(r, _ESYS_STATE_INIT, "SAPI error on SetCmdAuths");
 
+    /* Trigger execution and finish the async invocation */
     r = Tss2_Sys_ExecuteAsync(esysContext->sys);
-    return_if_error(r, "Finish (Execute Async)");
+    return_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Finish (Execute Async)");
 
     esysContext->state = _ESYS_STATE_SENT;
 
@@ -198,26 +202,34 @@
     ESYS_CONTEXT *esysContext)
 {
     LOG_TRACE("complete");
+    TSS2_RC r;
     if (esysContext == NULL) {
         LOG_ERROR("esyscontext is NULL.");
         return TSS2_ESYS_RC_BAD_REFERENCE;
     }
+
+    /* Check for correct sequence and set sequence to irregular for now */
     if (esysContext->state != _ESYS_STATE_SENT) {
         LOG_ERROR("Esys called in bad sequence.");
         return TSS2_ESYS_RC_BAD_SEQUENCE;
     }
-    TSS2_RC r;
+    esysContext->state = _ESYS_STATE_INTERNALERROR;
+
+    /*Receive the TPM response and handle resubmissions if necessary. */
     r = Tss2_Sys_ExecuteFinish(esysContext->sys, esysContext->timeout);
     if ((r & ~TSS2_RC_LAYER_MASK) == TSS2_BASE_RC_TRY_AGAIN) {
         LOG_DEBUG("A layer below returned TRY_AGAIN: %" PRIx32, r);
+        esysContext->state = _ESYS_STATE_SENT;
         return r;
     }
+    /* This block handle the resubmission of TPM commands given a certain set of
+     * TPM response codes. */
     if (r == TPM2_RC_RETRY || r == TPM2_RC_TESTING || r == TPM2_RC_YIELDED) {
         LOG_DEBUG("TPM returned RETRY, TESTING or YIELDED, which triggers a "
             "resubmission: %" PRIx32, r);
         if (esysContext->submissionCount >= _ESYS_MAX_SUBMISSIONS) {
-            LOG_WARNING("Maximum number of resubmissions has been reached.");
-            esysContext->state = _ESYS_STATE_ERRORRESPONSE;
+            LOG_WARNING("Maximum number of (re)submissions has been reached.");
+            esysContext->state = _ESYS_STATE_INIT;
             return r;
         }
         esysContext->state = _ESYS_STATE_RESUBMISSION;
@@ -228,33 +240,42 @@
                 esysContext->in.PolicyLocality.policySession,
                 esysContext->in.PolicyLocality.locality);
         if (r != TSS2_RC_SUCCESS) {
-            LOG_ERROR("Error attempting to resubmit");
+            LOG_WARNING("Error attempting to resubmit");
+            /* We do not set esysContext->state here but inherit the most recent
+             * state of the _async function. */
             return r;
         }
         r = TSS2_ESYS_RC_TRY_AGAIN;
+        LOG_DEBUG("Resubmission initiated and returning RC_TRY_AGAIN.");
         return r;
     }
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error finish (ExecuteFinish) PolicyLocality");
+    /* The following is the "regular error" handling. */
+    if (r != TSS2_RC_SUCCESS && (r & TSS2_RC_LAYER_MASK) == 0) {
+        LOG_WARNING("Received TPM Error");
+        esysContext->state = _ESYS_STATE_INIT;
+        return r;
+    } else if (r != TSS2_RC_SUCCESS) {
+        LOG_ERROR("Received a non-TPM Error");
+        esysContext->state = _ESYS_STATE_INTERNALERROR;
         return r;
     }
+
     /*
      * Now the verification of the response (hmac check) and if necessary the
-     * parameter decryption have to be done
+     * parameter decryption have to be done.
      */
     r = iesys_check_response(esysContext);
-    return_if_error(r, "Error: check response");
+    return_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Error: check response");
     /*
      * After the verification of the response we call the complete function
      * to deliver the result.
      */
     r = Tss2_Sys_PolicyLocality_Complete(esysContext->sys);
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error finish (ExecuteFinish) PolicyLocality: %" PRIx32, r);
-        esysContext->state = _ESYS_STATE_ERRORRESPONSE;
-        return r;;
-    }
-    esysContext->state = _ESYS_STATE_FINISHED;
+    return_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Received error from SAPI"
+                        " unmarshalling" );
+    esysContext->state = _ESYS_STATE_INIT;
+    LOG_DEBUG("context=%p",
+              esysContext);
 
-    return r;
+    return TSS2_RC_SUCCESS;
 }
diff --git a/src/tss2-esys/api/Esys_PolicyNV.c b/src/tss2-esys/api/Esys_PolicyNV.c
index a239219..14767de 100644
--- a/src/tss2-esys/api/Esys_PolicyNV.c
+++ b/src/tss2-esys/api/Esys_PolicyNV.c
@@ -182,6 +182,7 @@
     RSRC_NODE_T *nvIndexNode;
     RSRC_NODE_T *policySessionNode;
 
+    /* Check context, sequence correctness and set state to error for now */
     if (esysContext == NULL) {
         LOG_ERROR("esyscontext is NULL.");
         return TSS2_ESYS_RC_BAD_REFERENCE;
@@ -189,22 +190,25 @@
     r = iesys_check_sequence_async(esysContext);
     if (r != TSS2_RC_SUCCESS)
         return r;
-    r = check_session_feasability(shandle1, shandle2, shandle3, 1);
-    return_if_error(r, "Check session usage");
+    esysContext->state = _ESYS_STATE_INTERNALERROR;
 
+    /* Check and store input parameters */
+    r = check_session_feasability(shandle1, shandle2, shandle3, 1);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Check session usage");
     store_input_parameters(esysContext, authHandle, nvIndex, policySession,
                 operandB,
                 offset,
                 operation);
+
+    /* Retrieve the metadata objects for provided handles */
     r = esys_GetResourceObject(esysContext, authHandle, &authHandleNode);
-    if (r != TPM2_RC_SUCCESS)
-        return r;
+    return_state_if_error(r, _ESYS_STATE_INIT, "authHandle unknown.");
     r = esys_GetResourceObject(esysContext, nvIndex, &nvIndexNode);
-    if (r != TPM2_RC_SUCCESS)
-        return r;
+    return_state_if_error(r, _ESYS_STATE_INIT, "nvIndex unknown.");
     r = esys_GetResourceObject(esysContext, policySession, &policySessionNode);
-    if (r != TPM2_RC_SUCCESS)
-        return r;
+    return_state_if_error(r, _ESYS_STATE_INIT, "policySession unknown.");
+
+    /* Initial invocation of SAPI to prepare the command buffer with parameters */
     r = Tss2_Sys_PolicyNV_Prepare(esysContext->sys,
                 (authHandleNode == NULL) ? TPM2_RH_NULL : authHandleNode->rsrc.handle,
                 (nvIndexNode == NULL) ? TPM2_RH_NULL : nvIndexNode->rsrc.handle,
@@ -212,28 +216,26 @@
                 operandB,
                 offset,
                 operation);
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error async PolicyNV");
-        return r;
-    }
-    r = init_session_tab(esysContext, shandle1, shandle2, shandle3);
-    return_if_error(r, "Initialize session resources");
+    return_state_if_error(r, _ESYS_STATE_INIT, "SAPI Prepare returned error.");
 
+    /* Calculate the cpHash Values */
+    r = init_session_tab(esysContext, shandle1, shandle2, shandle3);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Initialize session resources");
     iesys_compute_session_value(esysContext->session_tab[0],
                 &authHandleNode->rsrc.name, &authHandleNode->auth);
     iesys_compute_session_value(esysContext->session_tab[1], NULL, NULL);
     iesys_compute_session_value(esysContext->session_tab[2], NULL, NULL);
-    r = iesys_gen_auths(esysContext, authHandleNode, nvIndexNode, policySessionNode, &auths);
-    return_if_error(r, "Error in computation of auth values");
 
+    /* Generate the auth values and set them in the SAPI command buffer */
+    r = iesys_gen_auths(esysContext, authHandleNode, nvIndexNode, policySessionNode, &auths);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Error in computation of auth values");
     esysContext->authsCount = auths.count;
     r = Tss2_Sys_SetCmdAuths(esysContext->sys, &auths);
-    if (r != TSS2_RC_SUCCESS) {
-        return r;
-    }
+    return_state_if_error(r, _ESYS_STATE_INIT, "SAPI error on SetCmdAuths");
 
+    /* Trigger execution and finish the async invocation */
     r = Tss2_Sys_ExecuteAsync(esysContext->sys);
-    return_if_error(r, "Finish (Execute Async)");
+    return_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Finish (Execute Async)");
 
     esysContext->state = _ESYS_STATE_SENT;
 
@@ -257,26 +259,34 @@
     ESYS_CONTEXT *esysContext)
 {
     LOG_TRACE("complete");
+    TSS2_RC r;
     if (esysContext == NULL) {
         LOG_ERROR("esyscontext is NULL.");
         return TSS2_ESYS_RC_BAD_REFERENCE;
     }
+
+    /* Check for correct sequence and set sequence to irregular for now */
     if (esysContext->state != _ESYS_STATE_SENT) {
         LOG_ERROR("Esys called in bad sequence.");
         return TSS2_ESYS_RC_BAD_SEQUENCE;
     }
-    TSS2_RC r;
+    esysContext->state = _ESYS_STATE_INTERNALERROR;
+
+    /*Receive the TPM response and handle resubmissions if necessary. */
     r = Tss2_Sys_ExecuteFinish(esysContext->sys, esysContext->timeout);
     if ((r & ~TSS2_RC_LAYER_MASK) == TSS2_BASE_RC_TRY_AGAIN) {
         LOG_DEBUG("A layer below returned TRY_AGAIN: %" PRIx32, r);
+        esysContext->state = _ESYS_STATE_SENT;
         return r;
     }
+    /* This block handle the resubmission of TPM commands given a certain set of
+     * TPM response codes. */
     if (r == TPM2_RC_RETRY || r == TPM2_RC_TESTING || r == TPM2_RC_YIELDED) {
         LOG_DEBUG("TPM returned RETRY, TESTING or YIELDED, which triggers a "
             "resubmission: %" PRIx32, r);
         if (esysContext->submissionCount >= _ESYS_MAX_SUBMISSIONS) {
-            LOG_WARNING("Maximum number of resubmissions has been reached.");
-            esysContext->state = _ESYS_STATE_ERRORRESPONSE;
+            LOG_WARNING("Maximum number of (re)submissions has been reached.");
+            esysContext->state = _ESYS_STATE_INIT;
             return r;
         }
         esysContext->state = _ESYS_STATE_RESUBMISSION;
@@ -291,33 +301,42 @@
                 esysContext->in.PolicyNV.offset,
                 esysContext->in.PolicyNV.operation);
         if (r != TSS2_RC_SUCCESS) {
-            LOG_ERROR("Error attempting to resubmit");
+            LOG_WARNING("Error attempting to resubmit");
+            /* We do not set esysContext->state here but inherit the most recent
+             * state of the _async function. */
             return r;
         }
         r = TSS2_ESYS_RC_TRY_AGAIN;
+        LOG_DEBUG("Resubmission initiated and returning RC_TRY_AGAIN.");
         return r;
     }
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error finish (ExecuteFinish) PolicyNV");
+    /* The following is the "regular error" handling. */
+    if (r != TSS2_RC_SUCCESS && (r & TSS2_RC_LAYER_MASK) == 0) {
+        LOG_WARNING("Received TPM Error");
+        esysContext->state = _ESYS_STATE_INIT;
+        return r;
+    } else if (r != TSS2_RC_SUCCESS) {
+        LOG_ERROR("Received a non-TPM Error");
+        esysContext->state = _ESYS_STATE_INTERNALERROR;
         return r;
     }
+
     /*
      * Now the verification of the response (hmac check) and if necessary the
-     * parameter decryption have to be done
+     * parameter decryption have to be done.
      */
     r = iesys_check_response(esysContext);
-    return_if_error(r, "Error: check response");
+    return_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Error: check response");
     /*
      * After the verification of the response we call the complete function
      * to deliver the result.
      */
     r = Tss2_Sys_PolicyNV_Complete(esysContext->sys);
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error finish (ExecuteFinish) PolicyNV: %" PRIx32, r);
-        esysContext->state = _ESYS_STATE_ERRORRESPONSE;
-        return r;;
-    }
-    esysContext->state = _ESYS_STATE_FINISHED;
+    return_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Received error from SAPI"
+                        " unmarshalling" );
+    esysContext->state = _ESYS_STATE_INIT;
+    LOG_DEBUG("context=%p",
+              esysContext);
 
-    return r;
+    return TSS2_RC_SUCCESS;
 }
diff --git a/src/tss2-esys/api/Esys_PolicyNameHash.c b/src/tss2-esys/api/Esys_PolicyNameHash.c
index 99dc7e1..b3f9d69 100644
--- a/src/tss2-esys/api/Esys_PolicyNameHash.c
+++ b/src/tss2-esys/api/Esys_PolicyNameHash.c
@@ -145,6 +145,7 @@
     TSS2_RC r;
     TSS2L_SYS_AUTH_COMMAND auths;
 
+    /* Check context, sequence correctness and set state to error for now */
     if (esysContext == NULL) {
         LOG_ERROR("esyscontext is NULL.");
         return TSS2_ESYS_RC_BAD_REFERENCE;
@@ -152,35 +153,38 @@
     r = iesys_check_sequence_async(esysContext);
     if (r != TSS2_RC_SUCCESS)
         return r;
-    r = check_session_feasability(shandle1, shandle2, shandle3, 0);
-    return_if_error(r, "Check session usage");
+    esysContext->state = _ESYS_STATE_INTERNALERROR;
 
+    /* Check and store input parameters */
+    r = check_session_feasability(shandle1, shandle2, shandle3, 0);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Check session usage");
     store_input_parameters(esysContext,
                 policySession,
                 nameHash);
+
+    /* Initial invocation of SAPI to prepare the command buffer with parameters */
     r = Tss2_Sys_PolicyNameHash_Prepare(esysContext->sys,
                 policySession,
                 nameHash);
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error async PolicyNameHash");
-        return r;
-    }
-    r = init_session_tab(esysContext, shandle1, shandle2, shandle3);
-    return_if_error(r, "Initialize session resources");
+    return_state_if_error(r, _ESYS_STATE_INIT, "SAPI Prepare returned error.");
 
+    /* Calculate the cpHash Values */
+    r = init_session_tab(esysContext, shandle1, shandle2, shandle3);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Initialize session resources");
     iesys_compute_session_value(esysContext->session_tab[0], NULL, NULL);
     iesys_compute_session_value(esysContext->session_tab[1], NULL, NULL);
-    r = iesys_gen_auths(esysContext, NULL, NULL, NULL, &auths);
-    return_if_error(r, "Error in computation of auth values");
+    iesys_compute_session_value(esysContext->session_tab[2], NULL, NULL);
 
+    /* Generate the auth values and set them in the SAPI command buffer */
+    r = iesys_gen_auths(esysContext, NULL, NULL, NULL, &auths);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Error in computation of auth values");
     esysContext->authsCount = auths.count;
     r = Tss2_Sys_SetCmdAuths(esysContext->sys, &auths);
-    if (r != TSS2_RC_SUCCESS) {
-        return r;
-    }
+    return_state_if_error(r, _ESYS_STATE_INIT, "SAPI error on SetCmdAuths");
 
+    /* Trigger execution and finish the async invocation */
     r = Tss2_Sys_ExecuteAsync(esysContext->sys);
-    return_if_error(r, "Finish (Execute Async)");
+    return_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Finish (Execute Async)");
 
     esysContext->state = _ESYS_STATE_SENT;
 
@@ -204,26 +208,34 @@
     ESYS_CONTEXT *esysContext)
 {
     LOG_TRACE("complete");
+    TSS2_RC r;
     if (esysContext == NULL) {
         LOG_ERROR("esyscontext is NULL.");
         return TSS2_ESYS_RC_BAD_REFERENCE;
     }
+
+    /* Check for correct sequence and set sequence to irregular for now */
     if (esysContext->state != _ESYS_STATE_SENT) {
         LOG_ERROR("Esys called in bad sequence.");
         return TSS2_ESYS_RC_BAD_SEQUENCE;
     }
-    TSS2_RC r;
+    esysContext->state = _ESYS_STATE_INTERNALERROR;
+
+    /*Receive the TPM response and handle resubmissions if necessary. */
     r = Tss2_Sys_ExecuteFinish(esysContext->sys, esysContext->timeout);
     if ((r & ~TSS2_RC_LAYER_MASK) == TSS2_BASE_RC_TRY_AGAIN) {
         LOG_DEBUG("A layer below returned TRY_AGAIN: %" PRIx32, r);
+        esysContext->state = _ESYS_STATE_SENT;
         return r;
     }
+    /* This block handle the resubmission of TPM commands given a certain set of
+     * TPM response codes. */
     if (r == TPM2_RC_RETRY || r == TPM2_RC_TESTING || r == TPM2_RC_YIELDED) {
         LOG_DEBUG("TPM returned RETRY, TESTING or YIELDED, which triggers a "
             "resubmission: %" PRIx32, r);
         if (esysContext->submissionCount >= _ESYS_MAX_SUBMISSIONS) {
-            LOG_WARNING("Maximum number of resubmissions has been reached.");
-            esysContext->state = _ESYS_STATE_ERRORRESPONSE;
+            LOG_WARNING("Maximum number of (re)submissions has been reached.");
+            esysContext->state = _ESYS_STATE_INIT;
             return r;
         }
         esysContext->state = _ESYS_STATE_RESUBMISSION;
@@ -234,33 +246,42 @@
                 esysContext->in.PolicyNameHash.policySession,
                 esysContext->in.PolicyNameHash.nameHash);
         if (r != TSS2_RC_SUCCESS) {
-            LOG_ERROR("Error attempting to resubmit");
+            LOG_WARNING("Error attempting to resubmit");
+            /* We do not set esysContext->state here but inherit the most recent
+             * state of the _async function. */
             return r;
         }
         r = TSS2_ESYS_RC_TRY_AGAIN;
+        LOG_DEBUG("Resubmission initiated and returning RC_TRY_AGAIN.");
         return r;
     }
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error finish (ExecuteFinish) PolicyNameHash");
+    /* The following is the "regular error" handling. */
+    if (r != TSS2_RC_SUCCESS && (r & TSS2_RC_LAYER_MASK) == 0) {
+        LOG_WARNING("Received TPM Error");
+        esysContext->state = _ESYS_STATE_INIT;
+        return r;
+    } else if (r != TSS2_RC_SUCCESS) {
+        LOG_ERROR("Received a non-TPM Error");
+        esysContext->state = _ESYS_STATE_INTERNALERROR;
         return r;
     }
+
     /*
      * Now the verification of the response (hmac check) and if necessary the
-     * parameter decryption have to be done
+     * parameter decryption have to be done.
      */
     r = iesys_check_response(esysContext);
-    return_if_error(r, "Error: check response");
+    return_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Error: check response");
     /*
      * After the verification of the response we call the complete function
      * to deliver the result.
      */
     r = Tss2_Sys_PolicyNameHash_Complete(esysContext->sys);
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error finish (ExecuteFinish) PolicyNameHash: %" PRIx32, r);
-        esysContext->state = _ESYS_STATE_ERRORRESPONSE;
-        return r;;
-    }
-    esysContext->state = _ESYS_STATE_FINISHED;
+    return_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Received error from SAPI"
+                        " unmarshalling" );
+    esysContext->state = _ESYS_STATE_INIT;
+    LOG_DEBUG("context=%p",
+              esysContext);
 
-    return r;
+    return TSS2_RC_SUCCESS;
 }
diff --git a/src/tss2-esys/api/Esys_PolicyNvWritten.c b/src/tss2-esys/api/Esys_PolicyNvWritten.c
index 8ba0e3e..2770ed4 100644
--- a/src/tss2-esys/api/Esys_PolicyNvWritten.c
+++ b/src/tss2-esys/api/Esys_PolicyNvWritten.c
@@ -142,6 +142,7 @@
     TSS2L_SYS_AUTH_COMMAND auths;
     RSRC_NODE_T *policySessionNode;
 
+    /* Check context, sequence correctness and set state to error for now */
     if (esysContext == NULL) {
         LOG_ERROR("esyscontext is NULL.");
         return TSS2_ESYS_RC_BAD_REFERENCE;
@@ -149,37 +150,41 @@
     r = iesys_check_sequence_async(esysContext);
     if (r != TSS2_RC_SUCCESS)
         return r;
-    r = check_session_feasability(shandle1, shandle2, shandle3, 0);
-    return_if_error(r, "Check session usage");
+    esysContext->state = _ESYS_STATE_INTERNALERROR;
 
+    /* Check and store input parameters */
+    r = check_session_feasability(shandle1, shandle2, shandle3, 0);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Check session usage");
     store_input_parameters(esysContext, policySession,
                 writtenSet);
+
+    /* Retrieve the metadata objects for provided handles */
     r = esys_GetResourceObject(esysContext, policySession, &policySessionNode);
-    if (r != TPM2_RC_SUCCESS)
-        return r;
+    return_state_if_error(r, _ESYS_STATE_INIT, "policySession unknown.");
+
+    /* Initial invocation of SAPI to prepare the command buffer with parameters */
     r = Tss2_Sys_PolicyNvWritten_Prepare(esysContext->sys,
                 (policySessionNode == NULL) ? TPM2_RH_NULL : policySessionNode->rsrc.handle,
                 writtenSet);
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error async PolicyNvWritten");
-        return r;
-    }
-    r = init_session_tab(esysContext, shandle1, shandle2, shandle3);
-    return_if_error(r, "Initialize session resources");
+    return_state_if_error(r, _ESYS_STATE_INIT, "SAPI Prepare returned error.");
 
+    /* Calculate the cpHash Values */
+    r = init_session_tab(esysContext, shandle1, shandle2, shandle3);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Initialize session resources");
     iesys_compute_session_value(esysContext->session_tab[0], NULL, NULL);
     iesys_compute_session_value(esysContext->session_tab[1], NULL, NULL);
-    r = iesys_gen_auths(esysContext, policySessionNode, NULL, NULL, &auths);
-    return_if_error(r, "Error in computation of auth values");
+    iesys_compute_session_value(esysContext->session_tab[2], NULL, NULL);
 
+    /* Generate the auth values and set them in the SAPI command buffer */
+    r = iesys_gen_auths(esysContext, policySessionNode, NULL, NULL, &auths);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Error in computation of auth values");
     esysContext->authsCount = auths.count;
     r = Tss2_Sys_SetCmdAuths(esysContext->sys, &auths);
-    if (r != TSS2_RC_SUCCESS) {
-        return r;
-    }
+    return_state_if_error(r, _ESYS_STATE_INIT, "SAPI error on SetCmdAuths");
 
+    /* Trigger execution and finish the async invocation */
     r = Tss2_Sys_ExecuteAsync(esysContext->sys);
-    return_if_error(r, "Finish (Execute Async)");
+    return_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Finish (Execute Async)");
 
     esysContext->state = _ESYS_STATE_SENT;
 
@@ -203,26 +208,34 @@
     ESYS_CONTEXT *esysContext)
 {
     LOG_TRACE("complete");
+    TSS2_RC r;
     if (esysContext == NULL) {
         LOG_ERROR("esyscontext is NULL.");
         return TSS2_ESYS_RC_BAD_REFERENCE;
     }
+
+    /* Check for correct sequence and set sequence to irregular for now */
     if (esysContext->state != _ESYS_STATE_SENT) {
         LOG_ERROR("Esys called in bad sequence.");
         return TSS2_ESYS_RC_BAD_SEQUENCE;
     }
-    TSS2_RC r;
+    esysContext->state = _ESYS_STATE_INTERNALERROR;
+
+    /*Receive the TPM response and handle resubmissions if necessary. */
     r = Tss2_Sys_ExecuteFinish(esysContext->sys, esysContext->timeout);
     if ((r & ~TSS2_RC_LAYER_MASK) == TSS2_BASE_RC_TRY_AGAIN) {
         LOG_DEBUG("A layer below returned TRY_AGAIN: %" PRIx32, r);
+        esysContext->state = _ESYS_STATE_SENT;
         return r;
     }
+    /* This block handle the resubmission of TPM commands given a certain set of
+     * TPM response codes. */
     if (r == TPM2_RC_RETRY || r == TPM2_RC_TESTING || r == TPM2_RC_YIELDED) {
         LOG_DEBUG("TPM returned RETRY, TESTING or YIELDED, which triggers a "
             "resubmission: %" PRIx32, r);
         if (esysContext->submissionCount >= _ESYS_MAX_SUBMISSIONS) {
-            LOG_WARNING("Maximum number of resubmissions has been reached.");
-            esysContext->state = _ESYS_STATE_ERRORRESPONSE;
+            LOG_WARNING("Maximum number of (re)submissions has been reached.");
+            esysContext->state = _ESYS_STATE_INIT;
             return r;
         }
         esysContext->state = _ESYS_STATE_RESUBMISSION;
@@ -233,33 +246,42 @@
                 esysContext->session_type[2],
                 esysContext->in.PolicyNvWritten.writtenSet);
         if (r != TSS2_RC_SUCCESS) {
-            LOG_ERROR("Error attempting to resubmit");
+            LOG_WARNING("Error attempting to resubmit");
+            /* We do not set esysContext->state here but inherit the most recent
+             * state of the _async function. */
             return r;
         }
         r = TSS2_ESYS_RC_TRY_AGAIN;
+        LOG_DEBUG("Resubmission initiated and returning RC_TRY_AGAIN.");
         return r;
     }
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error finish (ExecuteFinish) PolicyNvWritten");
+    /* The following is the "regular error" handling. */
+    if (r != TSS2_RC_SUCCESS && (r & TSS2_RC_LAYER_MASK) == 0) {
+        LOG_WARNING("Received TPM Error");
+        esysContext->state = _ESYS_STATE_INIT;
+        return r;
+    } else if (r != TSS2_RC_SUCCESS) {
+        LOG_ERROR("Received a non-TPM Error");
+        esysContext->state = _ESYS_STATE_INTERNALERROR;
         return r;
     }
+
     /*
      * Now the verification of the response (hmac check) and if necessary the
-     * parameter decryption have to be done
+     * parameter decryption have to be done.
      */
     r = iesys_check_response(esysContext);
-    return_if_error(r, "Error: check response");
+    return_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Error: check response");
     /*
      * After the verification of the response we call the complete function
      * to deliver the result.
      */
     r = Tss2_Sys_PolicyNvWritten_Complete(esysContext->sys);
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error finish (ExecuteFinish) PolicyNvWritten: %" PRIx32, r);
-        esysContext->state = _ESYS_STATE_ERRORRESPONSE;
-        return r;;
-    }
-    esysContext->state = _ESYS_STATE_FINISHED;
+    return_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Received error from SAPI"
+                        " unmarshalling" );
+    esysContext->state = _ESYS_STATE_INIT;
+    LOG_DEBUG("context=%p",
+              esysContext);
 
-    return r;
+    return TSS2_RC_SUCCESS;
 }
diff --git a/src/tss2-esys/api/Esys_PolicyOR.c b/src/tss2-esys/api/Esys_PolicyOR.c
index f892bb5..f43f901 100644
--- a/src/tss2-esys/api/Esys_PolicyOR.c
+++ b/src/tss2-esys/api/Esys_PolicyOR.c
@@ -148,6 +148,7 @@
     TSS2L_SYS_AUTH_COMMAND auths;
     RSRC_NODE_T *policySessionNode;
 
+    /* Check context, sequence correctness and set state to error for now */
     if (esysContext == NULL) {
         LOG_ERROR("esyscontext is NULL.");
         return TSS2_ESYS_RC_BAD_REFERENCE;
@@ -155,37 +156,41 @@
     r = iesys_check_sequence_async(esysContext);
     if (r != TSS2_RC_SUCCESS)
         return r;
-    r = check_session_feasability(shandle1, shandle2, shandle3, 0);
-    return_if_error(r, "Check session usage");
+    esysContext->state = _ESYS_STATE_INTERNALERROR;
 
+    /* Check and store input parameters */
+    r = check_session_feasability(shandle1, shandle2, shandle3, 0);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Check session usage");
     store_input_parameters(esysContext, policySession,
                 pHashList);
+
+    /* Retrieve the metadata objects for provided handles */
     r = esys_GetResourceObject(esysContext, policySession, &policySessionNode);
-    if (r != TPM2_RC_SUCCESS)
-        return r;
+    return_state_if_error(r, _ESYS_STATE_INIT, "policySession unknown.");
+
+    /* Initial invocation of SAPI to prepare the command buffer with parameters */
     r = Tss2_Sys_PolicyOR_Prepare(esysContext->sys,
                 (policySessionNode == NULL) ? TPM2_RH_NULL : policySessionNode->rsrc.handle,
                 pHashList);
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error async PolicyOR");
-        return r;
-    }
-    r = init_session_tab(esysContext, shandle1, shandle2, shandle3);
-    return_if_error(r, "Initialize session resources");
+    return_state_if_error(r, _ESYS_STATE_INIT, "SAPI Prepare returned error.");
 
+    /* Calculate the cpHash Values */
+    r = init_session_tab(esysContext, shandle1, shandle2, shandle3);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Initialize session resources");
     iesys_compute_session_value(esysContext->session_tab[0], NULL, NULL);
     iesys_compute_session_value(esysContext->session_tab[1], NULL, NULL);
-    r = iesys_gen_auths(esysContext, policySessionNode, NULL, NULL, &auths);
-    return_if_error(r, "Error in computation of auth values");
+    iesys_compute_session_value(esysContext->session_tab[2], NULL, NULL);
 
+    /* Generate the auth values and set them in the SAPI command buffer */
+    r = iesys_gen_auths(esysContext, policySessionNode, NULL, NULL, &auths);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Error in computation of auth values");
     esysContext->authsCount = auths.count;
     r = Tss2_Sys_SetCmdAuths(esysContext->sys, &auths);
-    if (r != TSS2_RC_SUCCESS) {
-        return r;
-    }
+    return_state_if_error(r, _ESYS_STATE_INIT, "SAPI error on SetCmdAuths");
 
+    /* Trigger execution and finish the async invocation */
     r = Tss2_Sys_ExecuteAsync(esysContext->sys);
-    return_if_error(r, "Finish (Execute Async)");
+    return_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Finish (Execute Async)");
 
     esysContext->state = _ESYS_STATE_SENT;
 
@@ -209,26 +214,34 @@
     ESYS_CONTEXT *esysContext)
 {
     LOG_TRACE("complete");
+    TSS2_RC r;
     if (esysContext == NULL) {
         LOG_ERROR("esyscontext is NULL.");
         return TSS2_ESYS_RC_BAD_REFERENCE;
     }
+
+    /* Check for correct sequence and set sequence to irregular for now */
     if (esysContext->state != _ESYS_STATE_SENT) {
         LOG_ERROR("Esys called in bad sequence.");
         return TSS2_ESYS_RC_BAD_SEQUENCE;
     }
-    TSS2_RC r;
+    esysContext->state = _ESYS_STATE_INTERNALERROR;
+
+    /*Receive the TPM response and handle resubmissions if necessary. */
     r = Tss2_Sys_ExecuteFinish(esysContext->sys, esysContext->timeout);
     if ((r & ~TSS2_RC_LAYER_MASK) == TSS2_BASE_RC_TRY_AGAIN) {
         LOG_DEBUG("A layer below returned TRY_AGAIN: %" PRIx32, r);
+        esysContext->state = _ESYS_STATE_SENT;
         return r;
     }
+    /* This block handle the resubmission of TPM commands given a certain set of
+     * TPM response codes. */
     if (r == TPM2_RC_RETRY || r == TPM2_RC_TESTING || r == TPM2_RC_YIELDED) {
         LOG_DEBUG("TPM returned RETRY, TESTING or YIELDED, which triggers a "
             "resubmission: %" PRIx32, r);
         if (esysContext->submissionCount >= _ESYS_MAX_SUBMISSIONS) {
-            LOG_WARNING("Maximum number of resubmissions has been reached.");
-            esysContext->state = _ESYS_STATE_ERRORRESPONSE;
+            LOG_WARNING("Maximum number of (re)submissions has been reached.");
+            esysContext->state = _ESYS_STATE_INIT;
             return r;
         }
         esysContext->state = _ESYS_STATE_RESUBMISSION;
@@ -239,33 +252,42 @@
                 esysContext->session_type[2],
                 esysContext->in.PolicyOR.pHashList);
         if (r != TSS2_RC_SUCCESS) {
-            LOG_ERROR("Error attempting to resubmit");
+            LOG_WARNING("Error attempting to resubmit");
+            /* We do not set esysContext->state here but inherit the most recent
+             * state of the _async function. */
             return r;
         }
         r = TSS2_ESYS_RC_TRY_AGAIN;
+        LOG_DEBUG("Resubmission initiated and returning RC_TRY_AGAIN.");
         return r;
     }
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error finish (ExecuteFinish) PolicyOR");
+    /* The following is the "regular error" handling. */
+    if (r != TSS2_RC_SUCCESS && (r & TSS2_RC_LAYER_MASK) == 0) {
+        LOG_WARNING("Received TPM Error");
+        esysContext->state = _ESYS_STATE_INIT;
+        return r;
+    } else if (r != TSS2_RC_SUCCESS) {
+        LOG_ERROR("Received a non-TPM Error");
+        esysContext->state = _ESYS_STATE_INTERNALERROR;
         return r;
     }
+
     /*
      * Now the verification of the response (hmac check) and if necessary the
-     * parameter decryption have to be done
+     * parameter decryption have to be done.
      */
     r = iesys_check_response(esysContext);
-    return_if_error(r, "Error: check response");
+    return_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Error: check response");
     /*
      * After the verification of the response we call the complete function
      * to deliver the result.
      */
     r = Tss2_Sys_PolicyOR_Complete(esysContext->sys);
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error finish (ExecuteFinish) PolicyOR: %" PRIx32, r);
-        esysContext->state = _ESYS_STATE_ERRORRESPONSE;
-        return r;;
-    }
-    esysContext->state = _ESYS_STATE_FINISHED;
+    return_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Received error from SAPI"
+                        " unmarshalling" );
+    esysContext->state = _ESYS_STATE_INIT;
+    LOG_DEBUG("context=%p",
+              esysContext);
 
-    return r;
+    return TSS2_RC_SUCCESS;
 }
diff --git a/src/tss2-esys/api/Esys_PolicyPCR.c b/src/tss2-esys/api/Esys_PolicyPCR.c
index 5112ef7..7b40b81 100644
--- a/src/tss2-esys/api/Esys_PolicyPCR.c
+++ b/src/tss2-esys/api/Esys_PolicyPCR.c
@@ -161,6 +161,7 @@
     TSS2L_SYS_AUTH_COMMAND auths;
     RSRC_NODE_T *policySessionNode;
 
+    /* Check context, sequence correctness and set state to error for now */
     if (esysContext == NULL) {
         LOG_ERROR("esyscontext is NULL.");
         return TSS2_ESYS_RC_BAD_REFERENCE;
@@ -168,40 +169,43 @@
     r = iesys_check_sequence_async(esysContext);
     if (r != TSS2_RC_SUCCESS)
         return r;
-    r = check_session_feasability(shandle1, shandle2, shandle3, 0);
-    return_if_error(r, "Check session usage");
+    esysContext->state = _ESYS_STATE_INTERNALERROR;
 
+    /* Check and store input parameters */
+    r = check_session_feasability(shandle1, shandle2, shandle3, 0);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Check session usage");
     store_input_parameters(esysContext, policySession,
                 pcrDigest,
                 pcrs);
+
+    /* Retrieve the metadata objects for provided handles */
     r = esys_GetResourceObject(esysContext, policySession, &policySessionNode);
-    if (r != TPM2_RC_SUCCESS)
-        return r;
+    return_state_if_error(r, _ESYS_STATE_INIT, "policySession unknown.");
+
+    /* Initial invocation of SAPI to prepare the command buffer with parameters */
     r = Tss2_Sys_PolicyPCR_Prepare(esysContext->sys,
                 (policySessionNode == NULL) ? TPM2_RH_NULL : policySessionNode->rsrc.handle,
                 pcrDigest,
                 pcrs);
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error async PolicyPCR");
-        return r;
-    }
-    r = init_session_tab(esysContext, shandle1, shandle2, shandle3);
-    return_if_error(r, "Initialize session resources");
+    return_state_if_error(r, _ESYS_STATE_INIT, "SAPI Prepare returned error.");
 
+    /* Calculate the cpHash Values */
+    r = init_session_tab(esysContext, shandle1, shandle2, shandle3);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Initialize session resources");
     iesys_compute_session_value(esysContext->session_tab[0], NULL, NULL);
     iesys_compute_session_value(esysContext->session_tab[1], NULL, NULL);
     iesys_compute_session_value(esysContext->session_tab[2], NULL, NULL);
-    r = iesys_gen_auths(esysContext, policySessionNode, NULL, NULL, &auths);
-    return_if_error(r, "Error in computation of auth values");
 
+    /* Generate the auth values and set them in the SAPI command buffer */
+    r = iesys_gen_auths(esysContext, policySessionNode, NULL, NULL, &auths);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Error in computation of auth values");
     esysContext->authsCount = auths.count;
     r = Tss2_Sys_SetCmdAuths(esysContext->sys, &auths);
-    if (r != TSS2_RC_SUCCESS) {
-        return r;
-    }
+    return_state_if_error(r, _ESYS_STATE_INIT, "SAPI error on SetCmdAuths");
 
+    /* Trigger execution and finish the async invocation */
     r = Tss2_Sys_ExecuteAsync(esysContext->sys);
-    return_if_error(r, "Finish (Execute Async)");
+    return_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Finish (Execute Async)");
 
     esysContext->state = _ESYS_STATE_SENT;
 
@@ -225,26 +229,34 @@
     ESYS_CONTEXT *esysContext)
 {
     LOG_TRACE("complete");
+    TSS2_RC r;
     if (esysContext == NULL) {
         LOG_ERROR("esyscontext is NULL.");
         return TSS2_ESYS_RC_BAD_REFERENCE;
     }
+
+    /* Check for correct sequence and set sequence to irregular for now */
     if (esysContext->state != _ESYS_STATE_SENT) {
         LOG_ERROR("Esys called in bad sequence.");
         return TSS2_ESYS_RC_BAD_SEQUENCE;
     }
-    TSS2_RC r;
+    esysContext->state = _ESYS_STATE_INTERNALERROR;
+
+    /*Receive the TPM response and handle resubmissions if necessary. */
     r = Tss2_Sys_ExecuteFinish(esysContext->sys, esysContext->timeout);
     if ((r & ~TSS2_RC_LAYER_MASK) == TSS2_BASE_RC_TRY_AGAIN) {
         LOG_DEBUG("A layer below returned TRY_AGAIN: %" PRIx32, r);
+        esysContext->state = _ESYS_STATE_SENT;
         return r;
     }
+    /* This block handle the resubmission of TPM commands given a certain set of
+     * TPM response codes. */
     if (r == TPM2_RC_RETRY || r == TPM2_RC_TESTING || r == TPM2_RC_YIELDED) {
         LOG_DEBUG("TPM returned RETRY, TESTING or YIELDED, which triggers a "
             "resubmission: %" PRIx32, r);
         if (esysContext->submissionCount >= _ESYS_MAX_SUBMISSIONS) {
-            LOG_WARNING("Maximum number of resubmissions has been reached.");
-            esysContext->state = _ESYS_STATE_ERRORRESPONSE;
+            LOG_WARNING("Maximum number of (re)submissions has been reached.");
+            esysContext->state = _ESYS_STATE_INIT;
             return r;
         }
         esysContext->state = _ESYS_STATE_RESUBMISSION;
@@ -256,33 +268,42 @@
                 esysContext->in.PolicyPCR.pcrDigest,
                 esysContext->in.PolicyPCR.pcrs);
         if (r != TSS2_RC_SUCCESS) {
-            LOG_ERROR("Error attempting to resubmit");
+            LOG_WARNING("Error attempting to resubmit");
+            /* We do not set esysContext->state here but inherit the most recent
+             * state of the _async function. */
             return r;
         }
         r = TSS2_ESYS_RC_TRY_AGAIN;
+        LOG_DEBUG("Resubmission initiated and returning RC_TRY_AGAIN.");
         return r;
     }
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error finish (ExecuteFinish) PolicyPCR");
+    /* The following is the "regular error" handling. */
+    if (r != TSS2_RC_SUCCESS && (r & TSS2_RC_LAYER_MASK) == 0) {
+        LOG_WARNING("Received TPM Error");
+        esysContext->state = _ESYS_STATE_INIT;
+        return r;
+    } else if (r != TSS2_RC_SUCCESS) {
+        LOG_ERROR("Received a non-TPM Error");
+        esysContext->state = _ESYS_STATE_INTERNALERROR;
         return r;
     }
+
     /*
      * Now the verification of the response (hmac check) and if necessary the
-     * parameter decryption have to be done
+     * parameter decryption have to be done.
      */
     r = iesys_check_response(esysContext);
-    return_if_error(r, "Error: check response");
+    return_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Error: check response");
     /*
      * After the verification of the response we call the complete function
      * to deliver the result.
      */
     r = Tss2_Sys_PolicyPCR_Complete(esysContext->sys);
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error finish (ExecuteFinish) PolicyPCR: %" PRIx32, r);
-        esysContext->state = _ESYS_STATE_ERRORRESPONSE;
-        return r;;
-    }
-    esysContext->state = _ESYS_STATE_FINISHED;
+    return_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Received error from SAPI"
+                        " unmarshalling" );
+    esysContext->state = _ESYS_STATE_INIT;
+    LOG_DEBUG("context=%p",
+              esysContext);
 
-    return r;
+    return TSS2_RC_SUCCESS;
 }
diff --git a/src/tss2-esys/api/Esys_PolicyPassword.c b/src/tss2-esys/api/Esys_PolicyPassword.c
index 4fdca30..6c86998 100644
--- a/src/tss2-esys/api/Esys_PolicyPassword.c
+++ b/src/tss2-esys/api/Esys_PolicyPassword.c
@@ -135,6 +135,7 @@
     TSS2L_SYS_AUTH_COMMAND auths;
     RSRC_NODE_T *policySessionNode;
 
+    /* Check context, sequence correctness and set state to error for now */
     if (esysContext == NULL) {
         LOG_ERROR("esyscontext is NULL.");
         return TSS2_ESYS_RC_BAD_REFERENCE;
@@ -142,34 +143,39 @@
     r = iesys_check_sequence_async(esysContext);
     if (r != TSS2_RC_SUCCESS)
         return r;
-    r = check_session_feasability(shandle1, shandle2, shandle3, 0);
-    return_if_error(r, "Check session usage");
+    esysContext->state = _ESYS_STATE_INTERNALERROR;
 
+    /* Check and store input parameters */
+    r = check_session_feasability(shandle1, shandle2, shandle3, 0);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Check session usage");
     store_input_parameters(esysContext, policySession);
+
+    /* Retrieve the metadata objects for provided handles */
     r = esys_GetResourceObject(esysContext, policySession, &policySessionNode);
-    if (r != TPM2_RC_SUCCESS)
-        return r;
+    return_state_if_error(r, _ESYS_STATE_INIT, "policySession unknown.");
+
+    /* Initial invocation of SAPI to prepare the command buffer with parameters */
     r = Tss2_Sys_PolicyPassword_Prepare(esysContext->sys,
                 (policySessionNode == NULL) ? TPM2_RH_NULL : policySessionNode->rsrc.handle);
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error async PolicyPassword");
-        return r;
-    }
+    return_state_if_error(r, _ESYS_STATE_INIT, "SAPI Prepare returned error.");
+
+    /* Calculate the cpHash Values */
     r = init_session_tab(esysContext, shandle1, shandle2, shandle3);
-    return_if_error(r, "Initialize session resources");
-
+    return_state_if_error(r, _ESYS_STATE_INIT, "Initialize session resources");
     iesys_compute_session_value(esysContext->session_tab[0], NULL, NULL);
-    r = iesys_gen_auths(esysContext, policySessionNode, NULL, NULL, &auths);
-    return_if_error(r, "Error in computation of auth values");
+    iesys_compute_session_value(esysContext->session_tab[1], NULL, NULL);
+    iesys_compute_session_value(esysContext->session_tab[2], NULL, NULL);
 
+    /* Generate the auth values and set them in the SAPI command buffer */
+    r = iesys_gen_auths(esysContext, policySessionNode, NULL, NULL, &auths);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Error in computation of auth values");
     esysContext->authsCount = auths.count;
     r = Tss2_Sys_SetCmdAuths(esysContext->sys, &auths);
-    if (r != TSS2_RC_SUCCESS) {
-        return r;
-    }
+    return_state_if_error(r, _ESYS_STATE_INIT, "SAPI error on SetCmdAuths");
 
+    /* Trigger execution and finish the async invocation */
     r = Tss2_Sys_ExecuteAsync(esysContext->sys);
-    return_if_error(r, "Finish (Execute Async)");
+    return_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Finish (Execute Async)");
 
     esysContext->state = _ESYS_STATE_SENT;
 
@@ -193,26 +199,34 @@
     ESYS_CONTEXT *esysContext)
 {
     LOG_TRACE("complete");
+    TSS2_RC r;
     if (esysContext == NULL) {
         LOG_ERROR("esyscontext is NULL.");
         return TSS2_ESYS_RC_BAD_REFERENCE;
     }
+
+    /* Check for correct sequence and set sequence to irregular for now */
     if (esysContext->state != _ESYS_STATE_SENT) {
         LOG_ERROR("Esys called in bad sequence.");
         return TSS2_ESYS_RC_BAD_SEQUENCE;
     }
-    TSS2_RC r;
+    esysContext->state = _ESYS_STATE_INTERNALERROR;
+
+    /*Receive the TPM response and handle resubmissions if necessary. */
     r = Tss2_Sys_ExecuteFinish(esysContext->sys, esysContext->timeout);
     if ((r & ~TSS2_RC_LAYER_MASK) == TSS2_BASE_RC_TRY_AGAIN) {
         LOG_DEBUG("A layer below returned TRY_AGAIN: %" PRIx32, r);
+        esysContext->state = _ESYS_STATE_SENT;
         return r;
     }
+    /* This block handle the resubmission of TPM commands given a certain set of
+     * TPM response codes. */
     if (r == TPM2_RC_RETRY || r == TPM2_RC_TESTING || r == TPM2_RC_YIELDED) {
         LOG_DEBUG("TPM returned RETRY, TESTING or YIELDED, which triggers a "
             "resubmission: %" PRIx32, r);
         if (esysContext->submissionCount >= _ESYS_MAX_SUBMISSIONS) {
-            LOG_WARNING("Maximum number of resubmissions has been reached.");
-            esysContext->state = _ESYS_STATE_ERRORRESPONSE;
+            LOG_WARNING("Maximum number of (re)submissions has been reached.");
+            esysContext->state = _ESYS_STATE_INIT;
             return r;
         }
         esysContext->state = _ESYS_STATE_RESUBMISSION;
@@ -222,40 +236,50 @@
                 esysContext->session_type[1],
                 esysContext->session_type[2]);
         if (r != TSS2_RC_SUCCESS) {
-            LOG_ERROR("Error attempting to resubmit");
+            LOG_WARNING("Error attempting to resubmit");
+            /* We do not set esysContext->state here but inherit the most recent
+             * state of the _async function. */
             return r;
         }
         r = TSS2_ESYS_RC_TRY_AGAIN;
+        LOG_DEBUG("Resubmission initiated and returning RC_TRY_AGAIN.");
         return r;
     }
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error finish (ExecuteFinish) PolicyPassword");
+    /* The following is the "regular error" handling. */
+    if (r != TSS2_RC_SUCCESS && (r & TSS2_RC_LAYER_MASK) == 0) {
+        LOG_WARNING("Received TPM Error");
+        esysContext->state = _ESYS_STATE_INIT;
+        return r;
+    } else if (r != TSS2_RC_SUCCESS) {
+        LOG_ERROR("Received a non-TPM Error");
+        esysContext->state = _ESYS_STATE_INTERNALERROR;
         return r;
     }
+
     /*
      * Now the verification of the response (hmac check) and if necessary the
-     * parameter decryption have to be done
+     * parameter decryption have to be done.
      */
     r = iesys_check_response(esysContext);
-    return_if_error(r, "Error: check response");
+    return_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Error: check response");
     /*
      * After the verification of the response we call the complete function
      * to deliver the result.
      */
     r = Tss2_Sys_PolicyPassword_Complete(esysContext->sys);
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error finish (ExecuteFinish) PolicyPassword: %" PRIx32, r);
-        esysContext->state = _ESYS_STATE_ERRORRESPONSE;
-        return r;;
-    }
+    return_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Received error from SAPI"
+                        " unmarshalling" );
     ESYS_TR policySession = esysContext->in.PolicyPassword.policySession;
     RSRC_NODE_T *policySessionNode;
     r = esys_GetResourceObject(esysContext, policySession, &policySessionNode);
     return_if_error(r, "get resource");
 
     if (policySessionNode != NULL)
-       policySessionNode->rsrc.misc.rsrc_session.type_policy_session = POLICY_PASSWORD;
-    esysContext->state = _ESYS_STATE_FINISHED;
+        /* Indicate that the authValue of authorized object will be checked */
+        policySessionNode->rsrc.misc.rsrc_session.type_policy_session = POLICY_PASSWORD;
+    esysContext->state = _ESYS_STATE_INIT;
+    LOG_DEBUG("context=%p",
+              esysContext);
 
-    return r;
+    return TSS2_RC_SUCCESS;
 }
diff --git a/src/tss2-esys/api/Esys_PolicyPhysicalPresence.c b/src/tss2-esys/api/Esys_PolicyPhysicalPresence.c
index 8a59a26..2edf8bb 100644
--- a/src/tss2-esys/api/Esys_PolicyPhysicalPresence.c
+++ b/src/tss2-esys/api/Esys_PolicyPhysicalPresence.c
@@ -135,6 +135,7 @@
     TSS2L_SYS_AUTH_COMMAND auths;
     RSRC_NODE_T *policySessionNode;
 
+    /* Check context, sequence correctness and set state to error for now */
     if (esysContext == NULL) {
         LOG_ERROR("esyscontext is NULL.");
         return TSS2_ESYS_RC_BAD_REFERENCE;
@@ -142,34 +143,39 @@
     r = iesys_check_sequence_async(esysContext);
     if (r != TSS2_RC_SUCCESS)
         return r;
-    r = check_session_feasability(shandle1, shandle2, shandle3, 0);
-    return_if_error(r, "Check session usage");
+    esysContext->state = _ESYS_STATE_INTERNALERROR;
 
+    /* Check and store input parameters */
+    r = check_session_feasability(shandle1, shandle2, shandle3, 0);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Check session usage");
     store_input_parameters(esysContext, policySession);
+
+    /* Retrieve the metadata objects for provided handles */
     r = esys_GetResourceObject(esysContext, policySession, &policySessionNode);
-    if (r != TPM2_RC_SUCCESS)
-        return r;
+    return_state_if_error(r, _ESYS_STATE_INIT, "policySession unknown.");
+
+    /* Initial invocation of SAPI to prepare the command buffer with parameters */
     r = Tss2_Sys_PolicyPhysicalPresence_Prepare(esysContext->sys,
                 (policySessionNode == NULL) ? TPM2_RH_NULL : policySessionNode->rsrc.handle);
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error async PolicyPhysicalPresence");
-        return r;
-    }
+    return_state_if_error(r, _ESYS_STATE_INIT, "SAPI Prepare returned error.");
+
+    /* Calculate the cpHash Values */
     r = init_session_tab(esysContext, shandle1, shandle2, shandle3);
-    return_if_error(r, "Initialize session resources");
-
+    return_state_if_error(r, _ESYS_STATE_INIT, "Initialize session resources");
     iesys_compute_session_value(esysContext->session_tab[0], NULL, NULL);
-    r = iesys_gen_auths(esysContext, policySessionNode, NULL, NULL, &auths);
-    return_if_error(r, "Error in computation of auth values");
+    iesys_compute_session_value(esysContext->session_tab[1], NULL, NULL);
+    iesys_compute_session_value(esysContext->session_tab[2], NULL, NULL);
 
+    /* Generate the auth values and set them in the SAPI command buffer */
+    r = iesys_gen_auths(esysContext, policySessionNode, NULL, NULL, &auths);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Error in computation of auth values");
     esysContext->authsCount = auths.count;
     r = Tss2_Sys_SetCmdAuths(esysContext->sys, &auths);
-    if (r != TSS2_RC_SUCCESS) {
-        return r;
-    }
+    return_state_if_error(r, _ESYS_STATE_INIT, "SAPI error on SetCmdAuths");
 
+    /* Trigger execution and finish the async invocation */
     r = Tss2_Sys_ExecuteAsync(esysContext->sys);
-    return_if_error(r, "Finish (Execute Async)");
+    return_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Finish (Execute Async)");
 
     esysContext->state = _ESYS_STATE_SENT;
 
@@ -193,26 +199,34 @@
     ESYS_CONTEXT *esysContext)
 {
     LOG_TRACE("complete");
+    TSS2_RC r;
     if (esysContext == NULL) {
         LOG_ERROR("esyscontext is NULL.");
         return TSS2_ESYS_RC_BAD_REFERENCE;
     }
+
+    /* Check for correct sequence and set sequence to irregular for now */
     if (esysContext->state != _ESYS_STATE_SENT) {
         LOG_ERROR("Esys called in bad sequence.");
         return TSS2_ESYS_RC_BAD_SEQUENCE;
     }
-    TSS2_RC r;
+    esysContext->state = _ESYS_STATE_INTERNALERROR;
+
+    /*Receive the TPM response and handle resubmissions if necessary. */
     r = Tss2_Sys_ExecuteFinish(esysContext->sys, esysContext->timeout);
     if ((r & ~TSS2_RC_LAYER_MASK) == TSS2_BASE_RC_TRY_AGAIN) {
         LOG_DEBUG("A layer below returned TRY_AGAIN: %" PRIx32, r);
+        esysContext->state = _ESYS_STATE_SENT;
         return r;
     }
+    /* This block handle the resubmission of TPM commands given a certain set of
+     * TPM response codes. */
     if (r == TPM2_RC_RETRY || r == TPM2_RC_TESTING || r == TPM2_RC_YIELDED) {
         LOG_DEBUG("TPM returned RETRY, TESTING or YIELDED, which triggers a "
             "resubmission: %" PRIx32, r);
         if (esysContext->submissionCount >= _ESYS_MAX_SUBMISSIONS) {
-            LOG_WARNING("Maximum number of resubmissions has been reached.");
-            esysContext->state = _ESYS_STATE_ERRORRESPONSE;
+            LOG_WARNING("Maximum number of (re)submissions has been reached.");
+            esysContext->state = _ESYS_STATE_INIT;
             return r;
         }
         esysContext->state = _ESYS_STATE_RESUBMISSION;
@@ -222,33 +236,42 @@
                 esysContext->session_type[1],
                 esysContext->session_type[2]);
         if (r != TSS2_RC_SUCCESS) {
-            LOG_ERROR("Error attempting to resubmit");
+            LOG_WARNING("Error attempting to resubmit");
+            /* We do not set esysContext->state here but inherit the most recent
+             * state of the _async function. */
             return r;
         }
         r = TSS2_ESYS_RC_TRY_AGAIN;
+        LOG_DEBUG("Resubmission initiated and returning RC_TRY_AGAIN.");
         return r;
     }
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error finish (ExecuteFinish) PolicyPhysicalPresence");
+    /* The following is the "regular error" handling. */
+    if (r != TSS2_RC_SUCCESS && (r & TSS2_RC_LAYER_MASK) == 0) {
+        LOG_WARNING("Received TPM Error");
+        esysContext->state = _ESYS_STATE_INIT;
+        return r;
+    } else if (r != TSS2_RC_SUCCESS) {
+        LOG_ERROR("Received a non-TPM Error");
+        esysContext->state = _ESYS_STATE_INTERNALERROR;
         return r;
     }
+
     /*
      * Now the verification of the response (hmac check) and if necessary the
-     * parameter decryption have to be done
+     * parameter decryption have to be done.
      */
     r = iesys_check_response(esysContext);
-    return_if_error(r, "Error: check response");
+    return_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Error: check response");
     /*
      * After the verification of the response we call the complete function
      * to deliver the result.
      */
     r = Tss2_Sys_PolicyPhysicalPresence_Complete(esysContext->sys);
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error finish (ExecuteFinish) PolicyPhysicalPresence: %" PRIx32, r);
-        esysContext->state = _ESYS_STATE_ERRORRESPONSE;
-        return r;;
-    }
-    esysContext->state = _ESYS_STATE_FINISHED;
+    return_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Received error from SAPI"
+                        " unmarshalling" );
+    esysContext->state = _ESYS_STATE_INIT;
+    LOG_DEBUG("context=%p",
+              esysContext);
 
-    return r;
+    return TSS2_RC_SUCCESS;
 }
diff --git a/src/tss2-esys/api/Esys_PolicyRestart.c b/src/tss2-esys/api/Esys_PolicyRestart.c
index 9744773..70a24c6 100644
--- a/src/tss2-esys/api/Esys_PolicyRestart.c
+++ b/src/tss2-esys/api/Esys_PolicyRestart.c
@@ -135,6 +135,7 @@
     TSS2L_SYS_AUTH_COMMAND auths;
     RSRC_NODE_T *sessionHandleNode;
 
+    /* Check context, sequence correctness and set state to error for now */
     if (esysContext == NULL) {
         LOG_ERROR("esyscontext is NULL.");
         return TSS2_ESYS_RC_BAD_REFERENCE;
@@ -142,34 +143,39 @@
     r = iesys_check_sequence_async(esysContext);
     if (r != TSS2_RC_SUCCESS)
         return r;
-    r = check_session_feasability(shandle1, shandle2, shandle3, 0);
-    return_if_error(r, "Check session usage");
+    esysContext->state = _ESYS_STATE_INTERNALERROR;
 
+    /* Check and store input parameters */
+    r = check_session_feasability(shandle1, shandle2, shandle3, 0);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Check session usage");
     store_input_parameters(esysContext, sessionHandle);
+
+    /* Retrieve the metadata objects for provided handles */
     r = esys_GetResourceObject(esysContext, sessionHandle, &sessionHandleNode);
-    if (r != TPM2_RC_SUCCESS)
-        return r;
+    return_state_if_error(r, _ESYS_STATE_INIT, "sessionHandle unknown.");
+
+    /* Initial invocation of SAPI to prepare the command buffer with parameters */
     r = Tss2_Sys_PolicyRestart_Prepare(esysContext->sys,
                 (sessionHandleNode == NULL) ? TPM2_RH_NULL : sessionHandleNode->rsrc.handle);
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error async PolicyRestart");
-        return r;
-    }
+    return_state_if_error(r, _ESYS_STATE_INIT, "SAPI Prepare returned error.");
+
+    /* Calculate the cpHash Values */
     r = init_session_tab(esysContext, shandle1, shandle2, shandle3);
-    return_if_error(r, "Initialize session resources");
-
+    return_state_if_error(r, _ESYS_STATE_INIT, "Initialize session resources");
     iesys_compute_session_value(esysContext->session_tab[0], NULL, NULL);
-    r = iesys_gen_auths(esysContext, sessionHandleNode, NULL, NULL, &auths);
-    return_if_error(r, "Error in computation of auth values");
+    iesys_compute_session_value(esysContext->session_tab[1], NULL, NULL);
+    iesys_compute_session_value(esysContext->session_tab[2], NULL, NULL);
 
+    /* Generate the auth values and set them in the SAPI command buffer */
+    r = iesys_gen_auths(esysContext, sessionHandleNode, NULL, NULL, &auths);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Error in computation of auth values");
     esysContext->authsCount = auths.count;
     r = Tss2_Sys_SetCmdAuths(esysContext->sys, &auths);
-    if (r != TSS2_RC_SUCCESS) {
-        return r;
-    }
+    return_state_if_error(r, _ESYS_STATE_INIT, "SAPI error on SetCmdAuths");
 
+    /* Trigger execution and finish the async invocation */
     r = Tss2_Sys_ExecuteAsync(esysContext->sys);
-    return_if_error(r, "Finish (Execute Async)");
+    return_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Finish (Execute Async)");
 
     esysContext->state = _ESYS_STATE_SENT;
 
@@ -193,26 +199,34 @@
     ESYS_CONTEXT *esysContext)
 {
     LOG_TRACE("complete");
+    TSS2_RC r;
     if (esysContext == NULL) {
         LOG_ERROR("esyscontext is NULL.");
         return TSS2_ESYS_RC_BAD_REFERENCE;
     }
+
+    /* Check for correct sequence and set sequence to irregular for now */
     if (esysContext->state != _ESYS_STATE_SENT) {
         LOG_ERROR("Esys called in bad sequence.");
         return TSS2_ESYS_RC_BAD_SEQUENCE;
     }
-    TSS2_RC r;
+    esysContext->state = _ESYS_STATE_INTERNALERROR;
+
+    /*Receive the TPM response and handle resubmissions if necessary. */
     r = Tss2_Sys_ExecuteFinish(esysContext->sys, esysContext->timeout);
     if ((r & ~TSS2_RC_LAYER_MASK) == TSS2_BASE_RC_TRY_AGAIN) {
         LOG_DEBUG("A layer below returned TRY_AGAIN: %" PRIx32, r);
+        esysContext->state = _ESYS_STATE_SENT;
         return r;
     }
+    /* This block handle the resubmission of TPM commands given a certain set of
+     * TPM response codes. */
     if (r == TPM2_RC_RETRY || r == TPM2_RC_TESTING || r == TPM2_RC_YIELDED) {
         LOG_DEBUG("TPM returned RETRY, TESTING or YIELDED, which triggers a "
             "resubmission: %" PRIx32, r);
         if (esysContext->submissionCount >= _ESYS_MAX_SUBMISSIONS) {
-            LOG_WARNING("Maximum number of resubmissions has been reached.");
-            esysContext->state = _ESYS_STATE_ERRORRESPONSE;
+            LOG_WARNING("Maximum number of (re)submissions has been reached.");
+            esysContext->state = _ESYS_STATE_INIT;
             return r;
         }
         esysContext->state = _ESYS_STATE_RESUBMISSION;
@@ -222,33 +236,42 @@
                 esysContext->session_type[1],
                 esysContext->session_type[2]);
         if (r != TSS2_RC_SUCCESS) {
-            LOG_ERROR("Error attempting to resubmit");
+            LOG_WARNING("Error attempting to resubmit");
+            /* We do not set esysContext->state here but inherit the most recent
+             * state of the _async function. */
             return r;
         }
         r = TSS2_ESYS_RC_TRY_AGAIN;
+        LOG_DEBUG("Resubmission initiated and returning RC_TRY_AGAIN.");
         return r;
     }
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error finish (ExecuteFinish) PolicyRestart");
+    /* The following is the "regular error" handling. */
+    if (r != TSS2_RC_SUCCESS && (r & TSS2_RC_LAYER_MASK) == 0) {
+        LOG_WARNING("Received TPM Error");
+        esysContext->state = _ESYS_STATE_INIT;
+        return r;
+    } else if (r != TSS2_RC_SUCCESS) {
+        LOG_ERROR("Received a non-TPM Error");
+        esysContext->state = _ESYS_STATE_INTERNALERROR;
         return r;
     }
+
     /*
      * Now the verification of the response (hmac check) and if necessary the
-     * parameter decryption have to be done
+     * parameter decryption have to be done.
      */
     r = iesys_check_response(esysContext);
-    return_if_error(r, "Error: check response");
+    return_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Error: check response");
     /*
      * After the verification of the response we call the complete function
      * to deliver the result.
      */
     r = Tss2_Sys_PolicyRestart_Complete(esysContext->sys);
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error finish (ExecuteFinish) PolicyRestart: %" PRIx32, r);
-        esysContext->state = _ESYS_STATE_ERRORRESPONSE;
-        return r;;
-    }
-    esysContext->state = _ESYS_STATE_FINISHED;
+    return_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Received error from SAPI"
+                        " unmarshalling" );
+    esysContext->state = _ESYS_STATE_INIT;
+    LOG_DEBUG("context=%p",
+              esysContext);
 
-    return r;
+    return TSS2_RC_SUCCESS;
 }
diff --git a/src/tss2-esys/api/Esys_PolicySecret.c b/src/tss2-esys/api/Esys_PolicySecret.c
index 60bcc04..37eada5 100644
--- a/src/tss2-esys/api/Esys_PolicySecret.c
+++ b/src/tss2-esys/api/Esys_PolicySecret.c
@@ -199,6 +199,7 @@
     RSRC_NODE_T *authHandleNode;
     RSRC_NODE_T *policySessionNode;
 
+    /* Check context, sequence correctness and set state to error for now */
     if (esysContext == NULL) {
         LOG_ERROR("esyscontext is NULL.");
         return TSS2_ESYS_RC_BAD_REFERENCE;
@@ -206,20 +207,24 @@
     r = iesys_check_sequence_async(esysContext);
     if (r != TSS2_RC_SUCCESS)
         return r;
-    r = check_session_feasability(shandle1, shandle2, shandle3, 1);
-    return_if_error(r, "Check session usage");
+    esysContext->state = _ESYS_STATE_INTERNALERROR;
 
+    /* Check and store input parameters */
+    r = check_session_feasability(shandle1, shandle2, shandle3, 1);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Check session usage");
     store_input_parameters(esysContext, authHandle, policySession,
                 nonceTPM,
                 cpHashA,
                 policyRef,
                 expiration);
+
+    /* Retrieve the metadata objects for provided handles */
     r = esys_GetResourceObject(esysContext, authHandle, &authHandleNode);
-    if (r != TPM2_RC_SUCCESS)
-        return r;
+    return_state_if_error(r, _ESYS_STATE_INIT, "authHandle unknown.");
     r = esys_GetResourceObject(esysContext, policySession, &policySessionNode);
-    if (r != TPM2_RC_SUCCESS)
-        return r;
+    return_state_if_error(r, _ESYS_STATE_INIT, "policySession unknown.");
+
+    /* Initial invocation of SAPI to prepare the command buffer with parameters */
     r = Tss2_Sys_PolicySecret_Prepare(esysContext->sys,
                 (authHandleNode == NULL) ? TPM2_RH_NULL : authHandleNode->rsrc.handle,
                 (policySessionNode == NULL) ? TPM2_RH_NULL : policySessionNode->rsrc.handle,
@@ -227,28 +232,26 @@
                 cpHashA,
                 policyRef,
                 expiration);
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error async PolicySecret");
-        return r;
-    }
-    r = init_session_tab(esysContext, shandle1, shandle2, shandle3);
-    return_if_error(r, "Initialize session resources");
+    return_state_if_error(r, _ESYS_STATE_INIT, "SAPI Prepare returned error.");
 
+    /* Calculate the cpHash Values */
+    r = init_session_tab(esysContext, shandle1, shandle2, shandle3);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Initialize session resources");
     iesys_compute_session_value(esysContext->session_tab[0],
                 &authHandleNode->rsrc.name, &authHandleNode->auth);
     iesys_compute_session_value(esysContext->session_tab[1], NULL, NULL);
     iesys_compute_session_value(esysContext->session_tab[2], NULL, NULL);
-    r = iesys_gen_auths(esysContext, authHandleNode, policySessionNode, NULL, &auths);
-    return_if_error(r, "Error in computation of auth values");
 
+    /* Generate the auth values and set them in the SAPI command buffer */
+    r = iesys_gen_auths(esysContext, authHandleNode, policySessionNode, NULL, &auths);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Error in computation of auth values");
     esysContext->authsCount = auths.count;
     r = Tss2_Sys_SetCmdAuths(esysContext->sys, &auths);
-    if (r != TSS2_RC_SUCCESS) {
-        return r;
-    }
+    return_state_if_error(r, _ESYS_STATE_INIT, "SAPI error on SetCmdAuths");
 
+    /* Trigger execution and finish the async invocation */
     r = Tss2_Sys_ExecuteAsync(esysContext->sys);
-    return_if_error(r, "Finish (Execute Async)");
+    return_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Finish (Execute Async)");
 
     esysContext->state = _ESYS_STATE_SENT;
 
@@ -278,15 +281,20 @@
     TPMT_TK_AUTH **policyTicket)
 {
     LOG_TRACE("complete");
+    TSS2_RC r;
     if (esysContext == NULL) {
         LOG_ERROR("esyscontext is NULL.");
         return TSS2_ESYS_RC_BAD_REFERENCE;
     }
+
+    /* Check for correct sequence and set sequence to irregular for now */
     if (esysContext->state != _ESYS_STATE_SENT) {
         LOG_ERROR("Esys called in bad sequence.");
         return TSS2_ESYS_RC_BAD_SEQUENCE;
     }
-    TSS2_RC r;
+    esysContext->state = _ESYS_STATE_INTERNALERROR;
+
+    /* Allocate memory for response parameters */
     if (timeout != NULL) {
         *timeout = calloc(sizeof(TPM2B_TIMEOUT), 1);
         if (*timeout == NULL) {
@@ -299,17 +307,22 @@
             goto_error(r, TSS2_ESYS_RC_MEMORY, "Out of memory", error_cleanup);
         }
     }
+
+    /*Receive the TPM response and handle resubmissions if necessary. */
     r = Tss2_Sys_ExecuteFinish(esysContext->sys, esysContext->timeout);
     if ((r & ~TSS2_RC_LAYER_MASK) == TSS2_BASE_RC_TRY_AGAIN) {
         LOG_DEBUG("A layer below returned TRY_AGAIN: %" PRIx32, r);
+        esysContext->state = _ESYS_STATE_SENT;
         goto error_cleanup;
     }
+    /* This block handle the resubmission of TPM commands given a certain set of
+     * TPM response codes. */
     if (r == TPM2_RC_RETRY || r == TPM2_RC_TESTING || r == TPM2_RC_YIELDED) {
         LOG_DEBUG("TPM returned RETRY, TESTING or YIELDED, which triggers a "
             "resubmission: %" PRIx32, r);
         if (esysContext->submissionCount >= _ESYS_MAX_SUBMISSIONS) {
-            LOG_WARNING("Maximum number of resubmissions has been reached.");
-            esysContext->state = _ESYS_STATE_ERRORRESPONSE;
+            LOG_WARNING("Maximum number of (re)submissions has been reached.");
+            esysContext->state = _ESYS_STATE_INIT;
             goto error_cleanup;
         }
         esysContext->state = _ESYS_STATE_RESUBMISSION;
@@ -324,22 +337,32 @@
                 esysContext->in.PolicySecret.policyRef,
                 esysContext->in.PolicySecret.expiration);
         if (r != TSS2_RC_SUCCESS) {
-            LOG_ERROR("Error attempting to resubmit");
+            LOG_WARNING("Error attempting to resubmit");
+            /* We do not set esysContext->state here but inherit the most recent
+             * state of the _async function. */
             goto error_cleanup;
         }
         r = TSS2_ESYS_RC_TRY_AGAIN;
+        LOG_DEBUG("Resubmission initiated and returning RC_TRY_AGAIN.");
         goto error_cleanup;
     }
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error finish (ExecuteFinish) PolicySecret");
+    /* The following is the "regular error" handling. */
+    if (r != TSS2_RC_SUCCESS && (r & TSS2_RC_LAYER_MASK) == 0) {
+        LOG_WARNING("Received TPM Error");
+        esysContext->state = _ESYS_STATE_INIT;
+        goto error_cleanup;
+    } else if (r != TSS2_RC_SUCCESS) {
+        LOG_ERROR("Received a non-TPM Error");
+        esysContext->state = _ESYS_STATE_INTERNALERROR;
         goto error_cleanup;
     }
+
     /*
      * Now the verification of the response (hmac check) and if necessary the
-     * parameter decryption have to be done
+     * parameter decryption have to be done.
      */
     r = iesys_check_response(esysContext);
-    goto_if_error(r, "Error: check response",
+    goto_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Error: check response",
                       error_cleanup);
     /*
      * After the verification of the response we call the complete function
@@ -348,19 +371,19 @@
     r = Tss2_Sys_PolicySecret_Complete(esysContext->sys,
                 (timeout != NULL) ? *timeout : NULL,
                 (policyTicket != NULL) ? *policyTicket : NULL);
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error finish (ExecuteFinish) PolicySecret: %" PRIx32, r);
-        esysContext->state = _ESYS_STATE_ERRORRESPONSE;
-        goto error_cleanup;;
-    }
-    esysContext->state = _ESYS_STATE_FINISHED;
+    goto_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Received error from SAPI"
+                        " unmarshalling" ,error_cleanup);
+    esysContext->state = _ESYS_STATE_INIT;
+    LOG_DEBUG("context=%p, timeout=%p, policyTicket=%p",
+              esysContext, timeout, policyTicket);
 
-    return r;
+    return TSS2_RC_SUCCESS;
 
 error_cleanup:
     if (timeout != NULL)
         SAFE_FREE(*timeout);
     if (policyTicket != NULL)
         SAFE_FREE(*policyTicket);
+
     return r;
 }
diff --git a/src/tss2-esys/api/Esys_PolicySigned.c b/src/tss2-esys/api/Esys_PolicySigned.c
index 691738f..e328d9c 100644
--- a/src/tss2-esys/api/Esys_PolicySigned.c
+++ b/src/tss2-esys/api/Esys_PolicySigned.c
@@ -212,6 +212,7 @@
     RSRC_NODE_T *authObjectNode;
     RSRC_NODE_T *policySessionNode;
 
+    /* Check context, sequence correctness and set state to error for now */
     if (esysContext == NULL) {
         LOG_ERROR("esyscontext is NULL.");
         return TSS2_ESYS_RC_BAD_REFERENCE;
@@ -219,21 +220,25 @@
     r = iesys_check_sequence_async(esysContext);
     if (r != TSS2_RC_SUCCESS)
         return r;
-    r = check_session_feasability(shandle1, shandle2, shandle3, 0);
-    return_if_error(r, "Check session usage");
+    esysContext->state = _ESYS_STATE_INTERNALERROR;
 
+    /* Check and store input parameters */
+    r = check_session_feasability(shandle1, shandle2, shandle3, 0);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Check session usage");
     store_input_parameters(esysContext, authObject, policySession,
                 nonceTPM,
                 cpHashA,
                 policyRef,
                 expiration,
                 auth);
+
+    /* Retrieve the metadata objects for provided handles */
     r = esys_GetResourceObject(esysContext, authObject, &authObjectNode);
-    if (r != TPM2_RC_SUCCESS)
-        return r;
+    return_state_if_error(r, _ESYS_STATE_INIT, "authObject unknown.");
     r = esys_GetResourceObject(esysContext, policySession, &policySessionNode);
-    if (r != TPM2_RC_SUCCESS)
-        return r;
+    return_state_if_error(r, _ESYS_STATE_INIT, "policySession unknown.");
+
+    /* Initial invocation of SAPI to prepare the command buffer with parameters */
     r = Tss2_Sys_PolicySigned_Prepare(esysContext->sys,
                 (authObjectNode == NULL) ? TPM2_RH_NULL : authObjectNode->rsrc.handle,
                 (policySessionNode == NULL) ? TPM2_RH_NULL : policySessionNode->rsrc.handle,
@@ -242,27 +247,25 @@
                 policyRef,
                 expiration,
                 auth);
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error async PolicySigned");
-        return r;
-    }
-    r = init_session_tab(esysContext, shandle1, shandle2, shandle3);
-    return_if_error(r, "Initialize session resources");
+    return_state_if_error(r, _ESYS_STATE_INIT, "SAPI Prepare returned error.");
 
+    /* Calculate the cpHash Values */
+    r = init_session_tab(esysContext, shandle1, shandle2, shandle3);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Initialize session resources");
     iesys_compute_session_value(esysContext->session_tab[0], NULL, NULL);
     iesys_compute_session_value(esysContext->session_tab[1], NULL, NULL);
     iesys_compute_session_value(esysContext->session_tab[2], NULL, NULL);
-    r = iesys_gen_auths(esysContext, authObjectNode, policySessionNode, NULL, &auths);
-    return_if_error(r, "Error in computation of auth values");
 
+    /* Generate the auth values and set them in the SAPI command buffer */
+    r = iesys_gen_auths(esysContext, authObjectNode, policySessionNode, NULL, &auths);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Error in computation of auth values");
     esysContext->authsCount = auths.count;
     r = Tss2_Sys_SetCmdAuths(esysContext->sys, &auths);
-    if (r != TSS2_RC_SUCCESS) {
-        return r;
-    }
+    return_state_if_error(r, _ESYS_STATE_INIT, "SAPI error on SetCmdAuths");
 
+    /* Trigger execution and finish the async invocation */
     r = Tss2_Sys_ExecuteAsync(esysContext->sys);
-    return_if_error(r, "Finish (Execute Async)");
+    return_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Finish (Execute Async)");
 
     esysContext->state = _ESYS_STATE_SENT;
 
@@ -292,15 +295,20 @@
     TPMT_TK_AUTH **policyTicket)
 {
     LOG_TRACE("complete");
+    TSS2_RC r;
     if (esysContext == NULL) {
         LOG_ERROR("esyscontext is NULL.");
         return TSS2_ESYS_RC_BAD_REFERENCE;
     }
+
+    /* Check for correct sequence and set sequence to irregular for now */
     if (esysContext->state != _ESYS_STATE_SENT) {
         LOG_ERROR("Esys called in bad sequence.");
         return TSS2_ESYS_RC_BAD_SEQUENCE;
     }
-    TSS2_RC r;
+    esysContext->state = _ESYS_STATE_INTERNALERROR;
+
+    /* Allocate memory for response parameters */
     if (timeout != NULL) {
         *timeout = calloc(sizeof(TPM2B_TIMEOUT), 1);
         if (*timeout == NULL) {
@@ -313,17 +321,22 @@
             goto_error(r, TSS2_ESYS_RC_MEMORY, "Out of memory", error_cleanup);
         }
     }
+
+    /*Receive the TPM response and handle resubmissions if necessary. */
     r = Tss2_Sys_ExecuteFinish(esysContext->sys, esysContext->timeout);
     if ((r & ~TSS2_RC_LAYER_MASK) == TSS2_BASE_RC_TRY_AGAIN) {
         LOG_DEBUG("A layer below returned TRY_AGAIN: %" PRIx32, r);
+        esysContext->state = _ESYS_STATE_SENT;
         goto error_cleanup;
     }
+    /* This block handle the resubmission of TPM commands given a certain set of
+     * TPM response codes. */
     if (r == TPM2_RC_RETRY || r == TPM2_RC_TESTING || r == TPM2_RC_YIELDED) {
         LOG_DEBUG("TPM returned RETRY, TESTING or YIELDED, which triggers a "
             "resubmission: %" PRIx32, r);
         if (esysContext->submissionCount >= _ESYS_MAX_SUBMISSIONS) {
-            LOG_WARNING("Maximum number of resubmissions has been reached.");
-            esysContext->state = _ESYS_STATE_ERRORRESPONSE;
+            LOG_WARNING("Maximum number of (re)submissions has been reached.");
+            esysContext->state = _ESYS_STATE_INIT;
             goto error_cleanup;
         }
         esysContext->state = _ESYS_STATE_RESUBMISSION;
@@ -339,22 +352,32 @@
                 esysContext->in.PolicySigned.expiration,
                 esysContext->in.PolicySigned.auth);
         if (r != TSS2_RC_SUCCESS) {
-            LOG_ERROR("Error attempting to resubmit");
+            LOG_WARNING("Error attempting to resubmit");
+            /* We do not set esysContext->state here but inherit the most recent
+             * state of the _async function. */
             goto error_cleanup;
         }
         r = TSS2_ESYS_RC_TRY_AGAIN;
+        LOG_DEBUG("Resubmission initiated and returning RC_TRY_AGAIN.");
         goto error_cleanup;
     }
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error finish (ExecuteFinish) PolicySigned");
+    /* The following is the "regular error" handling. */
+    if (r != TSS2_RC_SUCCESS && (r & TSS2_RC_LAYER_MASK) == 0) {
+        LOG_WARNING("Received TPM Error");
+        esysContext->state = _ESYS_STATE_INIT;
+        goto error_cleanup;
+    } else if (r != TSS2_RC_SUCCESS) {
+        LOG_ERROR("Received a non-TPM Error");
+        esysContext->state = _ESYS_STATE_INTERNALERROR;
         goto error_cleanup;
     }
+
     /*
      * Now the verification of the response (hmac check) and if necessary the
-     * parameter decryption have to be done
+     * parameter decryption have to be done.
      */
     r = iesys_check_response(esysContext);
-    goto_if_error(r, "Error: check response",
+    goto_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Error: check response",
                       error_cleanup);
     /*
      * After the verification of the response we call the complete function
@@ -363,19 +386,19 @@
     r = Tss2_Sys_PolicySigned_Complete(esysContext->sys,
                 (timeout != NULL) ? *timeout : NULL,
                 (policyTicket != NULL) ? *policyTicket : NULL);
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error finish (ExecuteFinish) PolicySigned: %" PRIx32, r);
-        esysContext->state = _ESYS_STATE_ERRORRESPONSE;
-        goto error_cleanup;;
-    }
-    esysContext->state = _ESYS_STATE_FINISHED;
+    goto_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Received error from SAPI"
+                        " unmarshalling" ,error_cleanup);
+    esysContext->state = _ESYS_STATE_INIT;
+    LOG_DEBUG("context=%p, timeout=%p, policyTicket=%p",
+              esysContext, timeout, policyTicket);
 
-    return r;
+    return TSS2_RC_SUCCESS;
 
 error_cleanup:
     if (timeout != NULL)
         SAFE_FREE(*timeout);
     if (policyTicket != NULL)
         SAFE_FREE(*policyTicket);
+
     return r;
 }
diff --git a/src/tss2-esys/api/Esys_PolicyTemplate.c b/src/tss2-esys/api/Esys_PolicyTemplate.c
index 3e514b8..da2608a 100644
--- a/src/tss2-esys/api/Esys_PolicyTemplate.c
+++ b/src/tss2-esys/api/Esys_PolicyTemplate.c
@@ -145,6 +145,7 @@
     TSS2_RC r;
     TSS2L_SYS_AUTH_COMMAND auths;
 
+    /* Check context, sequence correctness and set state to error for now */
     if (esysContext == NULL) {
         LOG_ERROR("esyscontext is NULL.");
         return TSS2_ESYS_RC_BAD_REFERENCE;
@@ -152,35 +153,38 @@
     r = iesys_check_sequence_async(esysContext);
     if (r != TSS2_RC_SUCCESS)
         return r;
-    r = check_session_feasability(shandle1, shandle2, shandle3, 0);
-    return_if_error(r, "Check session usage");
+    esysContext->state = _ESYS_STATE_INTERNALERROR;
 
+    /* Check and store input parameters */
+    r = check_session_feasability(shandle1, shandle2, shandle3, 0);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Check session usage");
     store_input_parameters(esysContext,
                 policySession,
                 templateHash);
+
+    /* Initial invocation of SAPI to prepare the command buffer with parameters */
     r = Tss2_Sys_PolicyTemplate_Prepare(esysContext->sys,
                 policySession,
                 templateHash);
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error async PolicyTemplate");
-        return r;
-    }
-    r = init_session_tab(esysContext, shandle1, shandle2, shandle3);
-    return_if_error(r, "Initialize session resources");
+    return_state_if_error(r, _ESYS_STATE_INIT, "SAPI Prepare returned error.");
 
+    /* Calculate the cpHash Values */
+    r = init_session_tab(esysContext, shandle1, shandle2, shandle3);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Initialize session resources");
     iesys_compute_session_value(esysContext->session_tab[0], NULL, NULL);
     iesys_compute_session_value(esysContext->session_tab[1], NULL, NULL);
-    r = iesys_gen_auths(esysContext, NULL, NULL, NULL, &auths);
-    return_if_error(r, "Error in computation of auth values");
+    iesys_compute_session_value(esysContext->session_tab[2], NULL, NULL);
 
+    /* Generate the auth values and set them in the SAPI command buffer */
+    r = iesys_gen_auths(esysContext, NULL, NULL, NULL, &auths);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Error in computation of auth values");
     esysContext->authsCount = auths.count;
     r = Tss2_Sys_SetCmdAuths(esysContext->sys, &auths);
-    if (r != TSS2_RC_SUCCESS) {
-        return r;
-    }
+    return_state_if_error(r, _ESYS_STATE_INIT, "SAPI error on SetCmdAuths");
 
+    /* Trigger execution and finish the async invocation */
     r = Tss2_Sys_ExecuteAsync(esysContext->sys);
-    return_if_error(r, "Finish (Execute Async)");
+    return_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Finish (Execute Async)");
 
     esysContext->state = _ESYS_STATE_SENT;
 
@@ -204,26 +208,34 @@
     ESYS_CONTEXT *esysContext)
 {
     LOG_TRACE("complete");
+    TSS2_RC r;
     if (esysContext == NULL) {
         LOG_ERROR("esyscontext is NULL.");
         return TSS2_ESYS_RC_BAD_REFERENCE;
     }
+
+    /* Check for correct sequence and set sequence to irregular for now */
     if (esysContext->state != _ESYS_STATE_SENT) {
         LOG_ERROR("Esys called in bad sequence.");
         return TSS2_ESYS_RC_BAD_SEQUENCE;
     }
-    TSS2_RC r;
+    esysContext->state = _ESYS_STATE_INTERNALERROR;
+
+    /*Receive the TPM response and handle resubmissions if necessary. */
     r = Tss2_Sys_ExecuteFinish(esysContext->sys, esysContext->timeout);
     if ((r & ~TSS2_RC_LAYER_MASK) == TSS2_BASE_RC_TRY_AGAIN) {
         LOG_DEBUG("A layer below returned TRY_AGAIN: %" PRIx32, r);
+        esysContext->state = _ESYS_STATE_SENT;
         return r;
     }
+    /* This block handle the resubmission of TPM commands given a certain set of
+     * TPM response codes. */
     if (r == TPM2_RC_RETRY || r == TPM2_RC_TESTING || r == TPM2_RC_YIELDED) {
         LOG_DEBUG("TPM returned RETRY, TESTING or YIELDED, which triggers a "
             "resubmission: %" PRIx32, r);
         if (esysContext->submissionCount >= _ESYS_MAX_SUBMISSIONS) {
-            LOG_WARNING("Maximum number of resubmissions has been reached.");
-            esysContext->state = _ESYS_STATE_ERRORRESPONSE;
+            LOG_WARNING("Maximum number of (re)submissions has been reached.");
+            esysContext->state = _ESYS_STATE_INIT;
             return r;
         }
         esysContext->state = _ESYS_STATE_RESUBMISSION;
@@ -234,33 +246,42 @@
                 esysContext->in.PolicyTemplate.policySession,
                 esysContext->in.PolicyTemplate.templateHash);
         if (r != TSS2_RC_SUCCESS) {
-            LOG_ERROR("Error attempting to resubmit");
+            LOG_WARNING("Error attempting to resubmit");
+            /* We do not set esysContext->state here but inherit the most recent
+             * state of the _async function. */
             return r;
         }
         r = TSS2_ESYS_RC_TRY_AGAIN;
+        LOG_DEBUG("Resubmission initiated and returning RC_TRY_AGAIN.");
         return r;
     }
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error finish (ExecuteFinish) PolicyTemplate");
+    /* The following is the "regular error" handling. */
+    if (r != TSS2_RC_SUCCESS && (r & TSS2_RC_LAYER_MASK) == 0) {
+        LOG_WARNING("Received TPM Error");
+        esysContext->state = _ESYS_STATE_INIT;
+        return r;
+    } else if (r != TSS2_RC_SUCCESS) {
+        LOG_ERROR("Received a non-TPM Error");
+        esysContext->state = _ESYS_STATE_INTERNALERROR;
         return r;
     }
+
     /*
      * Now the verification of the response (hmac check) and if necessary the
-     * parameter decryption have to be done
+     * parameter decryption have to be done.
      */
     r = iesys_check_response(esysContext);
-    return_if_error(r, "Error: check response");
+    return_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Error: check response");
     /*
      * After the verification of the response we call the complete function
      * to deliver the result.
      */
     r = Tss2_Sys_PolicyTemplate_Complete(esysContext->sys);
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error finish (ExecuteFinish) PolicyTemplate: %" PRIx32, r);
-        esysContext->state = _ESYS_STATE_ERRORRESPONSE;
-        return r;;
-    }
-    esysContext->state = _ESYS_STATE_FINISHED;
+    return_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Received error from SAPI"
+                        " unmarshalling" );
+    esysContext->state = _ESYS_STATE_INIT;
+    LOG_DEBUG("context=%p",
+              esysContext);
 
-    return r;
+    return TSS2_RC_SUCCESS;
 }
diff --git a/src/tss2-esys/api/Esys_PolicyTicket.c b/src/tss2-esys/api/Esys_PolicyTicket.c
index fae7644..bf4c57b 100644
--- a/src/tss2-esys/api/Esys_PolicyTicket.c
+++ b/src/tss2-esys/api/Esys_PolicyTicket.c
@@ -200,6 +200,7 @@
     TSS2L_SYS_AUTH_COMMAND auths;
     RSRC_NODE_T *policySessionNode;
 
+    /* Check context, sequence correctness and set state to error for now */
     if (esysContext == NULL) {
         LOG_ERROR("esyscontext is NULL.");
         return TSS2_ESYS_RC_BAD_REFERENCE;
@@ -207,18 +208,23 @@
     r = iesys_check_sequence_async(esysContext);
     if (r != TSS2_RC_SUCCESS)
         return r;
-    r = check_session_feasability(shandle1, shandle2, shandle3, 0);
-    return_if_error(r, "Check session usage");
+    esysContext->state = _ESYS_STATE_INTERNALERROR;
 
+    /* Check and store input parameters */
+    r = check_session_feasability(shandle1, shandle2, shandle3, 0);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Check session usage");
     store_input_parameters(esysContext, policySession,
                 timeout,
                 cpHashA,
                 policyRef,
                 authName,
                 ticket);
+
+    /* Retrieve the metadata objects for provided handles */
     r = esys_GetResourceObject(esysContext, policySession, &policySessionNode);
-    if (r != TPM2_RC_SUCCESS)
-        return r;
+    return_state_if_error(r, _ESYS_STATE_INIT, "policySession unknown.");
+
+    /* Initial invocation of SAPI to prepare the command buffer with parameters */
     r = Tss2_Sys_PolicyTicket_Prepare(esysContext->sys,
                 (policySessionNode == NULL) ? TPM2_RH_NULL : policySessionNode->rsrc.handle,
                 timeout,
@@ -226,27 +232,25 @@
                 policyRef,
                 authName,
                 ticket);
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error async PolicyTicket");
-        return r;
-    }
-    r = init_session_tab(esysContext, shandle1, shandle2, shandle3);
-    return_if_error(r, "Initialize session resources");
+    return_state_if_error(r, _ESYS_STATE_INIT, "SAPI Prepare returned error.");
 
+    /* Calculate the cpHash Values */
+    r = init_session_tab(esysContext, shandle1, shandle2, shandle3);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Initialize session resources");
     iesys_compute_session_value(esysContext->session_tab[0], NULL, NULL);
     iesys_compute_session_value(esysContext->session_tab[1], NULL, NULL);
     iesys_compute_session_value(esysContext->session_tab[2], NULL, NULL);
-    r = iesys_gen_auths(esysContext, policySessionNode, NULL, NULL, &auths);
-    return_if_error(r, "Error in computation of auth values");
 
+    /* Generate the auth values and set them in the SAPI command buffer */
+    r = iesys_gen_auths(esysContext, policySessionNode, NULL, NULL, &auths);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Error in computation of auth values");
     esysContext->authsCount = auths.count;
     r = Tss2_Sys_SetCmdAuths(esysContext->sys, &auths);
-    if (r != TSS2_RC_SUCCESS) {
-        return r;
-    }
+    return_state_if_error(r, _ESYS_STATE_INIT, "SAPI error on SetCmdAuths");
 
+    /* Trigger execution and finish the async invocation */
     r = Tss2_Sys_ExecuteAsync(esysContext->sys);
-    return_if_error(r, "Finish (Execute Async)");
+    return_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Finish (Execute Async)");
 
     esysContext->state = _ESYS_STATE_SENT;
 
@@ -270,26 +274,34 @@
     ESYS_CONTEXT *esysContext)
 {
     LOG_TRACE("complete");
+    TSS2_RC r;
     if (esysContext == NULL) {
         LOG_ERROR("esyscontext is NULL.");
         return TSS2_ESYS_RC_BAD_REFERENCE;
     }
+
+    /* Check for correct sequence and set sequence to irregular for now */
     if (esysContext->state != _ESYS_STATE_SENT) {
         LOG_ERROR("Esys called in bad sequence.");
         return TSS2_ESYS_RC_BAD_SEQUENCE;
     }
-    TSS2_RC r;
+    esysContext->state = _ESYS_STATE_INTERNALERROR;
+
+    /*Receive the TPM response and handle resubmissions if necessary. */
     r = Tss2_Sys_ExecuteFinish(esysContext->sys, esysContext->timeout);
     if ((r & ~TSS2_RC_LAYER_MASK) == TSS2_BASE_RC_TRY_AGAIN) {
         LOG_DEBUG("A layer below returned TRY_AGAIN: %" PRIx32, r);
+        esysContext->state = _ESYS_STATE_SENT;
         return r;
     }
+    /* This block handle the resubmission of TPM commands given a certain set of
+     * TPM response codes. */
     if (r == TPM2_RC_RETRY || r == TPM2_RC_TESTING || r == TPM2_RC_YIELDED) {
         LOG_DEBUG("TPM returned RETRY, TESTING or YIELDED, which triggers a "
             "resubmission: %" PRIx32, r);
         if (esysContext->submissionCount >= _ESYS_MAX_SUBMISSIONS) {
-            LOG_WARNING("Maximum number of resubmissions has been reached.");
-            esysContext->state = _ESYS_STATE_ERRORRESPONSE;
+            LOG_WARNING("Maximum number of (re)submissions has been reached.");
+            esysContext->state = _ESYS_STATE_INIT;
             return r;
         }
         esysContext->state = _ESYS_STATE_RESUBMISSION;
@@ -304,33 +316,42 @@
                 esysContext->in.PolicyTicket.authName,
                 esysContext->in.PolicyTicket.ticket);
         if (r != TSS2_RC_SUCCESS) {
-            LOG_ERROR("Error attempting to resubmit");
+            LOG_WARNING("Error attempting to resubmit");
+            /* We do not set esysContext->state here but inherit the most recent
+             * state of the _async function. */
             return r;
         }
         r = TSS2_ESYS_RC_TRY_AGAIN;
+        LOG_DEBUG("Resubmission initiated and returning RC_TRY_AGAIN.");
         return r;
     }
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error finish (ExecuteFinish) PolicyTicket");
+    /* The following is the "regular error" handling. */
+    if (r != TSS2_RC_SUCCESS && (r & TSS2_RC_LAYER_MASK) == 0) {
+        LOG_WARNING("Received TPM Error");
+        esysContext->state = _ESYS_STATE_INIT;
+        return r;
+    } else if (r != TSS2_RC_SUCCESS) {
+        LOG_ERROR("Received a non-TPM Error");
+        esysContext->state = _ESYS_STATE_INTERNALERROR;
         return r;
     }
+
     /*
      * Now the verification of the response (hmac check) and if necessary the
-     * parameter decryption have to be done
+     * parameter decryption have to be done.
      */
     r = iesys_check_response(esysContext);
-    return_if_error(r, "Error: check response");
+    return_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Error: check response");
     /*
      * After the verification of the response we call the complete function
      * to deliver the result.
      */
     r = Tss2_Sys_PolicyTicket_Complete(esysContext->sys);
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error finish (ExecuteFinish) PolicyTicket: %" PRIx32, r);
-        esysContext->state = _ESYS_STATE_ERRORRESPONSE;
-        return r;;
-    }
-    esysContext->state = _ESYS_STATE_FINISHED;
+    return_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Received error from SAPI"
+                        " unmarshalling" );
+    esysContext->state = _ESYS_STATE_INIT;
+    LOG_DEBUG("context=%p",
+              esysContext);
 
-    return r;
+    return TSS2_RC_SUCCESS;
 }
diff --git a/src/tss2-esys/api/Esys_Quote.c b/src/tss2-esys/api/Esys_Quote.c
index 3c4e11d..c344786 100644
--- a/src/tss2-esys/api/Esys_Quote.c
+++ b/src/tss2-esys/api/Esys_Quote.c
@@ -182,6 +182,7 @@
     TSS2L_SYS_AUTH_COMMAND auths;
     RSRC_NODE_T *signHandleNode;
 
+    /* Check context, sequence correctness and set state to error for now */
     if (esysContext == NULL) {
         LOG_ERROR("esyscontext is NULL.");
         return TSS2_ESYS_RC_BAD_REFERENCE;
@@ -189,43 +190,46 @@
     r = iesys_check_sequence_async(esysContext);
     if (r != TSS2_RC_SUCCESS)
         return r;
-    r = check_session_feasability(shandle1, shandle2, shandle3, 1);
-    return_if_error(r, "Check session usage");
+    esysContext->state = _ESYS_STATE_INTERNALERROR;
 
+    /* Check and store input parameters */
+    r = check_session_feasability(shandle1, shandle2, shandle3, 1);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Check session usage");
     store_input_parameters(esysContext, signHandle,
                 qualifyingData,
                 inScheme,
                 PCRselect);
+
+    /* Retrieve the metadata objects for provided handles */
     r = esys_GetResourceObject(esysContext, signHandle, &signHandleNode);
-    if (r != TPM2_RC_SUCCESS)
-        return r;
+    return_state_if_error(r, _ESYS_STATE_INIT, "signHandle unknown.");
+
+    /* Initial invocation of SAPI to prepare the command buffer with parameters */
     r = Tss2_Sys_Quote_Prepare(esysContext->sys,
                 (signHandleNode == NULL) ? TPM2_RH_NULL : signHandleNode->rsrc.handle,
                 qualifyingData,
                 inScheme,
                 PCRselect);
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error async Quote");
-        return r;
-    }
-    r = init_session_tab(esysContext, shandle1, shandle2, shandle3);
-    return_if_error(r, "Initialize session resources");
+    return_state_if_error(r, _ESYS_STATE_INIT, "SAPI Prepare returned error.");
 
+    /* Calculate the cpHash Values */
+    r = init_session_tab(esysContext, shandle1, shandle2, shandle3);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Initialize session resources");
     iesys_compute_session_value(esysContext->session_tab[0],
                 &signHandleNode->rsrc.name, &signHandleNode->auth);
     iesys_compute_session_value(esysContext->session_tab[1], NULL, NULL);
     iesys_compute_session_value(esysContext->session_tab[2], NULL, NULL);
-    r = iesys_gen_auths(esysContext, signHandleNode, NULL, NULL, &auths);
-    return_if_error(r, "Error in computation of auth values");
 
+    /* Generate the auth values and set them in the SAPI command buffer */
+    r = iesys_gen_auths(esysContext, signHandleNode, NULL, NULL, &auths);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Error in computation of auth values");
     esysContext->authsCount = auths.count;
     r = Tss2_Sys_SetCmdAuths(esysContext->sys, &auths);
-    if (r != TSS2_RC_SUCCESS) {
-        return r;
-    }
+    return_state_if_error(r, _ESYS_STATE_INIT, "SAPI error on SetCmdAuths");
 
+    /* Trigger execution and finish the async invocation */
     r = Tss2_Sys_ExecuteAsync(esysContext->sys);
-    return_if_error(r, "Finish (Execute Async)");
+    return_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Finish (Execute Async)");
 
     esysContext->state = _ESYS_STATE_SENT;
 
@@ -255,15 +259,20 @@
     TPMT_SIGNATURE **signature)
 {
     LOG_TRACE("complete");
+    TSS2_RC r;
     if (esysContext == NULL) {
         LOG_ERROR("esyscontext is NULL.");
         return TSS2_ESYS_RC_BAD_REFERENCE;
     }
+
+    /* Check for correct sequence and set sequence to irregular for now */
     if (esysContext->state != _ESYS_STATE_SENT) {
         LOG_ERROR("Esys called in bad sequence.");
         return TSS2_ESYS_RC_BAD_SEQUENCE;
     }
-    TSS2_RC r;
+    esysContext->state = _ESYS_STATE_INTERNALERROR;
+
+    /* Allocate memory for response parameters */
     if (quoted != NULL) {
         *quoted = calloc(sizeof(TPM2B_ATTEST), 1);
         if (*quoted == NULL) {
@@ -276,17 +285,22 @@
             goto_error(r, TSS2_ESYS_RC_MEMORY, "Out of memory", error_cleanup);
         }
     }
+
+    /*Receive the TPM response and handle resubmissions if necessary. */
     r = Tss2_Sys_ExecuteFinish(esysContext->sys, esysContext->timeout);
     if ((r & ~TSS2_RC_LAYER_MASK) == TSS2_BASE_RC_TRY_AGAIN) {
         LOG_DEBUG("A layer below returned TRY_AGAIN: %" PRIx32, r);
+        esysContext->state = _ESYS_STATE_SENT;
         goto error_cleanup;
     }
+    /* This block handle the resubmission of TPM commands given a certain set of
+     * TPM response codes. */
     if (r == TPM2_RC_RETRY || r == TPM2_RC_TESTING || r == TPM2_RC_YIELDED) {
         LOG_DEBUG("TPM returned RETRY, TESTING or YIELDED, which triggers a "
             "resubmission: %" PRIx32, r);
         if (esysContext->submissionCount >= _ESYS_MAX_SUBMISSIONS) {
-            LOG_WARNING("Maximum number of resubmissions has been reached.");
-            esysContext->state = _ESYS_STATE_ERRORRESPONSE;
+            LOG_WARNING("Maximum number of (re)submissions has been reached.");
+            esysContext->state = _ESYS_STATE_INIT;
             goto error_cleanup;
         }
         esysContext->state = _ESYS_STATE_RESUBMISSION;
@@ -299,22 +313,32 @@
                 esysContext->in.Quote.inScheme,
                 esysContext->in.Quote.PCRselect);
         if (r != TSS2_RC_SUCCESS) {
-            LOG_ERROR("Error attempting to resubmit");
+            LOG_WARNING("Error attempting to resubmit");
+            /* We do not set esysContext->state here but inherit the most recent
+             * state of the _async function. */
             goto error_cleanup;
         }
         r = TSS2_ESYS_RC_TRY_AGAIN;
+        LOG_DEBUG("Resubmission initiated and returning RC_TRY_AGAIN.");
         goto error_cleanup;
     }
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error finish (ExecuteFinish) Quote");
+    /* The following is the "regular error" handling. */
+    if (r != TSS2_RC_SUCCESS && (r & TSS2_RC_LAYER_MASK) == 0) {
+        LOG_WARNING("Received TPM Error");
+        esysContext->state = _ESYS_STATE_INIT;
+        goto error_cleanup;
+    } else if (r != TSS2_RC_SUCCESS) {
+        LOG_ERROR("Received a non-TPM Error");
+        esysContext->state = _ESYS_STATE_INTERNALERROR;
         goto error_cleanup;
     }
+
     /*
      * Now the verification of the response (hmac check) and if necessary the
-     * parameter decryption have to be done
+     * parameter decryption have to be done.
      */
     r = iesys_check_response(esysContext);
-    goto_if_error(r, "Error: check response",
+    goto_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Error: check response",
                       error_cleanup);
     /*
      * After the verification of the response we call the complete function
@@ -323,19 +347,19 @@
     r = Tss2_Sys_Quote_Complete(esysContext->sys,
                 (quoted != NULL) ? *quoted : NULL,
                 (signature != NULL) ? *signature : NULL);
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error finish (ExecuteFinish) Quote: %" PRIx32, r);
-        esysContext->state = _ESYS_STATE_ERRORRESPONSE;
-        goto error_cleanup;;
-    }
-    esysContext->state = _ESYS_STATE_FINISHED;
+    goto_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Received error from SAPI"
+                        " unmarshalling" ,error_cleanup);
+    esysContext->state = _ESYS_STATE_INIT;
+    LOG_DEBUG("context=%p, quoted=%p, signature=%p",
+              esysContext, quoted, signature);
 
-    return r;
+    return TSS2_RC_SUCCESS;
 
 error_cleanup:
     if (quoted != NULL)
         SAFE_FREE(*quoted);
     if (signature != NULL)
         SAFE_FREE(*signature);
+
     return r;
 }
diff --git a/src/tss2-esys/api/Esys_RSA_Decrypt.c b/src/tss2-esys/api/Esys_RSA_Decrypt.c
index f682a74..4ea57b2 100644
--- a/src/tss2-esys/api/Esys_RSA_Decrypt.c
+++ b/src/tss2-esys/api/Esys_RSA_Decrypt.c
@@ -178,6 +178,7 @@
     TSS2L_SYS_AUTH_COMMAND auths;
     RSRC_NODE_T *keyHandleNode;
 
+    /* Check context, sequence correctness and set state to error for now */
     if (esysContext == NULL) {
         LOG_ERROR("esyscontext is NULL.");
         return TSS2_ESYS_RC_BAD_REFERENCE;
@@ -185,43 +186,46 @@
     r = iesys_check_sequence_async(esysContext);
     if (r != TSS2_RC_SUCCESS)
         return r;
-    r = check_session_feasability(shandle1, shandle2, shandle3, 1);
-    return_if_error(r, "Check session usage");
+    esysContext->state = _ESYS_STATE_INTERNALERROR;
 
+    /* Check and store input parameters */
+    r = check_session_feasability(shandle1, shandle2, shandle3, 1);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Check session usage");
     store_input_parameters(esysContext, keyHandle,
                 cipherText,
                 inScheme,
                 label);
+
+    /* Retrieve the metadata objects for provided handles */
     r = esys_GetResourceObject(esysContext, keyHandle, &keyHandleNode);
-    if (r != TPM2_RC_SUCCESS)
-        return r;
+    return_state_if_error(r, _ESYS_STATE_INIT, "keyHandle unknown.");
+
+    /* Initial invocation of SAPI to prepare the command buffer with parameters */
     r = Tss2_Sys_RSA_Decrypt_Prepare(esysContext->sys,
                 (keyHandleNode == NULL) ? TPM2_RH_NULL : keyHandleNode->rsrc.handle,
                 cipherText,
                 inScheme,
                 label);
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error async RSA_Decrypt");
-        return r;
-    }
-    r = init_session_tab(esysContext, shandle1, shandle2, shandle3);
-    return_if_error(r, "Initialize session resources");
+    return_state_if_error(r, _ESYS_STATE_INIT, "SAPI Prepare returned error.");
 
+    /* Calculate the cpHash Values */
+    r = init_session_tab(esysContext, shandle1, shandle2, shandle3);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Initialize session resources");
     iesys_compute_session_value(esysContext->session_tab[0],
                 &keyHandleNode->rsrc.name, &keyHandleNode->auth);
     iesys_compute_session_value(esysContext->session_tab[1], NULL, NULL);
     iesys_compute_session_value(esysContext->session_tab[2], NULL, NULL);
-    r = iesys_gen_auths(esysContext, keyHandleNode, NULL, NULL, &auths);
-    return_if_error(r, "Error in computation of auth values");
 
+    /* Generate the auth values and set them in the SAPI command buffer */
+    r = iesys_gen_auths(esysContext, keyHandleNode, NULL, NULL, &auths);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Error in computation of auth values");
     esysContext->authsCount = auths.count;
     r = Tss2_Sys_SetCmdAuths(esysContext->sys, &auths);
-    if (r != TSS2_RC_SUCCESS) {
-        return r;
-    }
+    return_state_if_error(r, _ESYS_STATE_INIT, "SAPI error on SetCmdAuths");
 
+    /* Trigger execution and finish the async invocation */
     r = Tss2_Sys_ExecuteAsync(esysContext->sys);
-    return_if_error(r, "Finish (Execute Async)");
+    return_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Finish (Execute Async)");
 
     esysContext->state = _ESYS_STATE_SENT;
 
@@ -248,32 +252,42 @@
     TPM2B_PUBLIC_KEY_RSA **message)
 {
     LOG_TRACE("complete");
+    TSS2_RC r;
     if (esysContext == NULL) {
         LOG_ERROR("esyscontext is NULL.");
         return TSS2_ESYS_RC_BAD_REFERENCE;
     }
+
+    /* Check for correct sequence and set sequence to irregular for now */
     if (esysContext->state != _ESYS_STATE_SENT) {
         LOG_ERROR("Esys called in bad sequence.");
         return TSS2_ESYS_RC_BAD_SEQUENCE;
     }
-    TSS2_RC r;
+    esysContext->state = _ESYS_STATE_INTERNALERROR;
+
+    /* Allocate memory for response parameters */
     if (message != NULL) {
         *message = calloc(sizeof(TPM2B_PUBLIC_KEY_RSA), 1);
         if (*message == NULL) {
             return_error(TSS2_ESYS_RC_MEMORY, "Out of memory");
         }
     }
+
+    /*Receive the TPM response and handle resubmissions if necessary. */
     r = Tss2_Sys_ExecuteFinish(esysContext->sys, esysContext->timeout);
     if ((r & ~TSS2_RC_LAYER_MASK) == TSS2_BASE_RC_TRY_AGAIN) {
         LOG_DEBUG("A layer below returned TRY_AGAIN: %" PRIx32, r);
+        esysContext->state = _ESYS_STATE_SENT;
         goto error_cleanup;
     }
+    /* This block handle the resubmission of TPM commands given a certain set of
+     * TPM response codes. */
     if (r == TPM2_RC_RETRY || r == TPM2_RC_TESTING || r == TPM2_RC_YIELDED) {
         LOG_DEBUG("TPM returned RETRY, TESTING or YIELDED, which triggers a "
             "resubmission: %" PRIx32, r);
         if (esysContext->submissionCount >= _ESYS_MAX_SUBMISSIONS) {
-            LOG_WARNING("Maximum number of resubmissions has been reached.");
-            esysContext->state = _ESYS_STATE_ERRORRESPONSE;
+            LOG_WARNING("Maximum number of (re)submissions has been reached.");
+            esysContext->state = _ESYS_STATE_INIT;
             goto error_cleanup;
         }
         esysContext->state = _ESYS_STATE_RESUBMISSION;
@@ -286,22 +300,32 @@
                 esysContext->in.RSA_Decrypt.inScheme,
                 esysContext->in.RSA_Decrypt.label);
         if (r != TSS2_RC_SUCCESS) {
-            LOG_ERROR("Error attempting to resubmit");
+            LOG_WARNING("Error attempting to resubmit");
+            /* We do not set esysContext->state here but inherit the most recent
+             * state of the _async function. */
             goto error_cleanup;
         }
         r = TSS2_ESYS_RC_TRY_AGAIN;
+        LOG_DEBUG("Resubmission initiated and returning RC_TRY_AGAIN.");
         goto error_cleanup;
     }
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error finish (ExecuteFinish) RSA_Decrypt");
+    /* The following is the "regular error" handling. */
+    if (r != TSS2_RC_SUCCESS && (r & TSS2_RC_LAYER_MASK) == 0) {
+        LOG_WARNING("Received TPM Error");
+        esysContext->state = _ESYS_STATE_INIT;
+        goto error_cleanup;
+    } else if (r != TSS2_RC_SUCCESS) {
+        LOG_ERROR("Received a non-TPM Error");
+        esysContext->state = _ESYS_STATE_INTERNALERROR;
         goto error_cleanup;
     }
+
     /*
      * Now the verification of the response (hmac check) and if necessary the
-     * parameter decryption have to be done
+     * parameter decryption have to be done.
      */
     r = iesys_check_response(esysContext);
-    goto_if_error(r, "Error: check response",
+    goto_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Error: check response",
                       error_cleanup);
     /*
      * After the verification of the response we call the complete function
@@ -309,17 +333,17 @@
      */
     r = Tss2_Sys_RSA_Decrypt_Complete(esysContext->sys,
                 (message != NULL) ? *message : NULL);
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error finish (ExecuteFinish) RSA_Decrypt: %" PRIx32, r);
-        esysContext->state = _ESYS_STATE_ERRORRESPONSE;
-        goto error_cleanup;;
-    }
-    esysContext->state = _ESYS_STATE_FINISHED;
+    goto_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Received error from SAPI"
+                        " unmarshalling" ,error_cleanup);
+    esysContext->state = _ESYS_STATE_INIT;
+    LOG_DEBUG("context=%p, message=%p",
+              esysContext, message);
 
-    return r;
+    return TSS2_RC_SUCCESS;
 
 error_cleanup:
     if (message != NULL)
         SAFE_FREE(*message);
+
     return r;
 }
diff --git a/src/tss2-esys/api/Esys_RSA_Encrypt.c b/src/tss2-esys/api/Esys_RSA_Encrypt.c
index bdc48bc..76bdc1c 100644
--- a/src/tss2-esys/api/Esys_RSA_Encrypt.c
+++ b/src/tss2-esys/api/Esys_RSA_Encrypt.c
@@ -178,6 +178,7 @@
     TSS2L_SYS_AUTH_COMMAND auths;
     RSRC_NODE_T *keyHandleNode;
 
+    /* Check context, sequence correctness and set state to error for now */
     if (esysContext == NULL) {
         LOG_ERROR("esyscontext is NULL.");
         return TSS2_ESYS_RC_BAD_REFERENCE;
@@ -185,42 +186,45 @@
     r = iesys_check_sequence_async(esysContext);
     if (r != TSS2_RC_SUCCESS)
         return r;
-    r = check_session_feasability(shandle1, shandle2, shandle3, 0);
-    return_if_error(r, "Check session usage");
+    esysContext->state = _ESYS_STATE_INTERNALERROR;
 
+    /* Check and store input parameters */
+    r = check_session_feasability(shandle1, shandle2, shandle3, 0);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Check session usage");
     store_input_parameters(esysContext, keyHandle,
                 message,
                 inScheme,
                 label);
+
+    /* Retrieve the metadata objects for provided handles */
     r = esys_GetResourceObject(esysContext, keyHandle, &keyHandleNode);
-    if (r != TPM2_RC_SUCCESS)
-        return r;
+    return_state_if_error(r, _ESYS_STATE_INIT, "keyHandle unknown.");
+
+    /* Initial invocation of SAPI to prepare the command buffer with parameters */
     r = Tss2_Sys_RSA_Encrypt_Prepare(esysContext->sys,
                 (keyHandleNode == NULL) ? TPM2_RH_NULL : keyHandleNode->rsrc.handle,
                 message,
                 inScheme,
                 label);
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error async RSA_Encrypt");
-        return r;
-    }
-    r = init_session_tab(esysContext, shandle1, shandle2, shandle3);
-    return_if_error(r, "Initialize session resources");
+    return_state_if_error(r, _ESYS_STATE_INIT, "SAPI Prepare returned error.");
 
+    /* Calculate the cpHash Values */
+    r = init_session_tab(esysContext, shandle1, shandle2, shandle3);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Initialize session resources");
     iesys_compute_session_value(esysContext->session_tab[0], NULL, NULL);
     iesys_compute_session_value(esysContext->session_tab[1], NULL, NULL);
     iesys_compute_session_value(esysContext->session_tab[2], NULL, NULL);
-    r = iesys_gen_auths(esysContext, keyHandleNode, NULL, NULL, &auths);
-    return_if_error(r, "Error in computation of auth values");
 
+    /* Generate the auth values and set them in the SAPI command buffer */
+    r = iesys_gen_auths(esysContext, keyHandleNode, NULL, NULL, &auths);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Error in computation of auth values");
     esysContext->authsCount = auths.count;
     r = Tss2_Sys_SetCmdAuths(esysContext->sys, &auths);
-    if (r != TSS2_RC_SUCCESS) {
-        return r;
-    }
+    return_state_if_error(r, _ESYS_STATE_INIT, "SAPI error on SetCmdAuths");
 
+    /* Trigger execution and finish the async invocation */
     r = Tss2_Sys_ExecuteAsync(esysContext->sys);
-    return_if_error(r, "Finish (Execute Async)");
+    return_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Finish (Execute Async)");
 
     esysContext->state = _ESYS_STATE_SENT;
 
@@ -247,32 +251,42 @@
     TPM2B_PUBLIC_KEY_RSA **outData)
 {
     LOG_TRACE("complete");
+    TSS2_RC r;
     if (esysContext == NULL) {
         LOG_ERROR("esyscontext is NULL.");
         return TSS2_ESYS_RC_BAD_REFERENCE;
     }
+
+    /* Check for correct sequence and set sequence to irregular for now */
     if (esysContext->state != _ESYS_STATE_SENT) {
         LOG_ERROR("Esys called in bad sequence.");
         return TSS2_ESYS_RC_BAD_SEQUENCE;
     }
-    TSS2_RC r;
+    esysContext->state = _ESYS_STATE_INTERNALERROR;
+
+    /* Allocate memory for response parameters */
     if (outData != NULL) {
         *outData = calloc(sizeof(TPM2B_PUBLIC_KEY_RSA), 1);
         if (*outData == NULL) {
             return_error(TSS2_ESYS_RC_MEMORY, "Out of memory");
         }
     }
+
+    /*Receive the TPM response and handle resubmissions if necessary. */
     r = Tss2_Sys_ExecuteFinish(esysContext->sys, esysContext->timeout);
     if ((r & ~TSS2_RC_LAYER_MASK) == TSS2_BASE_RC_TRY_AGAIN) {
         LOG_DEBUG("A layer below returned TRY_AGAIN: %" PRIx32, r);
+        esysContext->state = _ESYS_STATE_SENT;
         goto error_cleanup;
     }
+    /* This block handle the resubmission of TPM commands given a certain set of
+     * TPM response codes. */
     if (r == TPM2_RC_RETRY || r == TPM2_RC_TESTING || r == TPM2_RC_YIELDED) {
         LOG_DEBUG("TPM returned RETRY, TESTING or YIELDED, which triggers a "
             "resubmission: %" PRIx32, r);
         if (esysContext->submissionCount >= _ESYS_MAX_SUBMISSIONS) {
-            LOG_WARNING("Maximum number of resubmissions has been reached.");
-            esysContext->state = _ESYS_STATE_ERRORRESPONSE;
+            LOG_WARNING("Maximum number of (re)submissions has been reached.");
+            esysContext->state = _ESYS_STATE_INIT;
             goto error_cleanup;
         }
         esysContext->state = _ESYS_STATE_RESUBMISSION;
@@ -285,22 +299,32 @@
                 esysContext->in.RSA_Encrypt.inScheme,
                 esysContext->in.RSA_Encrypt.label);
         if (r != TSS2_RC_SUCCESS) {
-            LOG_ERROR("Error attempting to resubmit");
+            LOG_WARNING("Error attempting to resubmit");
+            /* We do not set esysContext->state here but inherit the most recent
+             * state of the _async function. */
             goto error_cleanup;
         }
         r = TSS2_ESYS_RC_TRY_AGAIN;
+        LOG_DEBUG("Resubmission initiated and returning RC_TRY_AGAIN.");
         goto error_cleanup;
     }
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error finish (ExecuteFinish) RSA_Encrypt");
+    /* The following is the "regular error" handling. */
+    if (r != TSS2_RC_SUCCESS && (r & TSS2_RC_LAYER_MASK) == 0) {
+        LOG_WARNING("Received TPM Error");
+        esysContext->state = _ESYS_STATE_INIT;
+        goto error_cleanup;
+    } else if (r != TSS2_RC_SUCCESS) {
+        LOG_ERROR("Received a non-TPM Error");
+        esysContext->state = _ESYS_STATE_INTERNALERROR;
         goto error_cleanup;
     }
+
     /*
      * Now the verification of the response (hmac check) and if necessary the
-     * parameter decryption have to be done
+     * parameter decryption have to be done.
      */
     r = iesys_check_response(esysContext);
-    goto_if_error(r, "Error: check response",
+    goto_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Error: check response",
                       error_cleanup);
     /*
      * After the verification of the response we call the complete function
@@ -308,17 +332,17 @@
      */
     r = Tss2_Sys_RSA_Encrypt_Complete(esysContext->sys,
                 (outData != NULL) ? *outData : NULL);
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error finish (ExecuteFinish) RSA_Encrypt: %" PRIx32, r);
-        esysContext->state = _ESYS_STATE_ERRORRESPONSE;
-        goto error_cleanup;;
-    }
-    esysContext->state = _ESYS_STATE_FINISHED;
+    goto_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Received error from SAPI"
+                        " unmarshalling" ,error_cleanup);
+    esysContext->state = _ESYS_STATE_INIT;
+    LOG_DEBUG("context=%p, outData=%p",
+              esysContext, outData);
 
-    return r;
+    return TSS2_RC_SUCCESS;
 
 error_cleanup:
     if (outData != NULL)
         SAFE_FREE(*outData);
+
     return r;
 }
diff --git a/src/tss2-esys/api/Esys_ReadClock.c b/src/tss2-esys/api/Esys_ReadClock.c
index df4e9cd..fbd0e13 100644
--- a/src/tss2-esys/api/Esys_ReadClock.c
+++ b/src/tss2-esys/api/Esys_ReadClock.c
@@ -124,6 +124,7 @@
     TSS2_RC r;
     TSS2L_SYS_AUTH_COMMAND auths;
 
+    /* Check context, sequence correctness and set state to error for now */
     if (esysContext == NULL) {
         LOG_ERROR("esyscontext is NULL.");
         return TSS2_ESYS_RC_BAD_REFERENCE;
@@ -131,27 +132,33 @@
     r = iesys_check_sequence_async(esysContext);
     if (r != TSS2_RC_SUCCESS)
         return r;
+    esysContext->state = _ESYS_STATE_INTERNALERROR;
+
+    /* Check and store input parameters */
     r = check_session_feasability(shandle1, shandle2, shandle3, 0);
-    return_if_error(r, "Check session usage");
+    return_state_if_error(r, _ESYS_STATE_INIT, "Check session usage");
+
+    /* Initial invocation of SAPI to prepare the command buffer with parameters */
     r = Tss2_Sys_ReadClock_Prepare(esysContext->sys);
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error async ReadClock");
-        return r;
-    }
+    return_state_if_error(r, _ESYS_STATE_INIT, "SAPI Prepare returned error.");
+
+    /* Calculate the cpHash Values */
     r = init_session_tab(esysContext, shandle1, shandle2, shandle3);
-    return_if_error(r, "Initialize session resources");
+    return_state_if_error(r, _ESYS_STATE_INIT, "Initialize session resources");
+    iesys_compute_session_value(esysContext->session_tab[0], NULL, NULL);
+    iesys_compute_session_value(esysContext->session_tab[1], NULL, NULL);
+    iesys_compute_session_value(esysContext->session_tab[2], NULL, NULL);
 
+    /* Generate the auth values and set them in the SAPI command buffer */
     r = iesys_gen_auths(esysContext, NULL, NULL, NULL, &auths);
-    return_if_error(r, "Error in computation of auth values");
-
+    return_state_if_error(r, _ESYS_STATE_INIT, "Error in computation of auth values");
     esysContext->authsCount = auths.count;
     r = Tss2_Sys_SetCmdAuths(esysContext->sys, &auths);
-    if (r != TSS2_RC_SUCCESS) {
-        return r;
-    }
+    return_state_if_error(r, _ESYS_STATE_INIT, "SAPI error on SetCmdAuths");
 
+    /* Trigger execution and finish the async invocation */
     r = Tss2_Sys_ExecuteAsync(esysContext->sys);
-    return_if_error(r, "Finish (Execute Async)");
+    return_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Finish (Execute Async)");
 
     esysContext->state = _ESYS_STATE_SENT;
 
@@ -178,32 +185,42 @@
     TPMS_TIME_INFO **currentTime)
 {
     LOG_TRACE("complete");
+    TSS2_RC r;
     if (esysContext == NULL) {
         LOG_ERROR("esyscontext is NULL.");
         return TSS2_ESYS_RC_BAD_REFERENCE;
     }
+
+    /* Check for correct sequence and set sequence to irregular for now */
     if (esysContext->state != _ESYS_STATE_SENT) {
         LOG_ERROR("Esys called in bad sequence.");
         return TSS2_ESYS_RC_BAD_SEQUENCE;
     }
-    TSS2_RC r;
+    esysContext->state = _ESYS_STATE_INTERNALERROR;
+
+    /* Allocate memory for response parameters */
     if (currentTime != NULL) {
         *currentTime = calloc(sizeof(TPMS_TIME_INFO), 1);
         if (*currentTime == NULL) {
             return_error(TSS2_ESYS_RC_MEMORY, "Out of memory");
         }
     }
+
+    /*Receive the TPM response and handle resubmissions if necessary. */
     r = Tss2_Sys_ExecuteFinish(esysContext->sys, esysContext->timeout);
     if ((r & ~TSS2_RC_LAYER_MASK) == TSS2_BASE_RC_TRY_AGAIN) {
         LOG_DEBUG("A layer below returned TRY_AGAIN: %" PRIx32, r);
+        esysContext->state = _ESYS_STATE_SENT;
         goto error_cleanup;
     }
+    /* This block handle the resubmission of TPM commands given a certain set of
+     * TPM response codes. */
     if (r == TPM2_RC_RETRY || r == TPM2_RC_TESTING || r == TPM2_RC_YIELDED) {
         LOG_DEBUG("TPM returned RETRY, TESTING or YIELDED, which triggers a "
             "resubmission: %" PRIx32, r);
         if (esysContext->submissionCount >= _ESYS_MAX_SUBMISSIONS) {
-            LOG_WARNING("Maximum number of resubmissions has been reached.");
-            esysContext->state = _ESYS_STATE_ERRORRESPONSE;
+            LOG_WARNING("Maximum number of (re)submissions has been reached.");
+            esysContext->state = _ESYS_STATE_INIT;
             goto error_cleanup;
         }
         esysContext->state = _ESYS_STATE_RESUBMISSION;
@@ -212,22 +229,32 @@
                 esysContext->session_type[1],
                 esysContext->session_type[2]);
         if (r != TSS2_RC_SUCCESS) {
-            LOG_ERROR("Error attempting to resubmit");
+            LOG_WARNING("Error attempting to resubmit");
+            /* We do not set esysContext->state here but inherit the most recent
+             * state of the _async function. */
             goto error_cleanup;
         }
         r = TSS2_ESYS_RC_TRY_AGAIN;
+        LOG_DEBUG("Resubmission initiated and returning RC_TRY_AGAIN.");
         goto error_cleanup;
     }
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error finish (ExecuteFinish) ReadClock");
+    /* The following is the "regular error" handling. */
+    if (r != TSS2_RC_SUCCESS && (r & TSS2_RC_LAYER_MASK) == 0) {
+        LOG_WARNING("Received TPM Error");
+        esysContext->state = _ESYS_STATE_INIT;
+        goto error_cleanup;
+    } else if (r != TSS2_RC_SUCCESS) {
+        LOG_ERROR("Received a non-TPM Error");
+        esysContext->state = _ESYS_STATE_INTERNALERROR;
         goto error_cleanup;
     }
+
     /*
      * Now the verification of the response (hmac check) and if necessary the
-     * parameter decryption have to be done
+     * parameter decryption have to be done.
      */
     r = iesys_check_response(esysContext);
-    goto_if_error(r, "Error: check response",
+    goto_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Error: check response",
                       error_cleanup);
     /*
      * After the verification of the response we call the complete function
@@ -235,17 +262,17 @@
      */
     r = Tss2_Sys_ReadClock_Complete(esysContext->sys,
                 (currentTime != NULL) ? *currentTime : NULL);
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error finish (ExecuteFinish) ReadClock: %" PRIx32, r);
-        esysContext->state = _ESYS_STATE_ERRORRESPONSE;
-        goto error_cleanup;;
-    }
-    esysContext->state = _ESYS_STATE_FINISHED;
+    goto_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Received error from SAPI"
+                        " unmarshalling" ,error_cleanup);
+    esysContext->state = _ESYS_STATE_INIT;
+    LOG_DEBUG("context=%p, currentTime=%p",
+              esysContext, currentTime);
 
-    return r;
+    return TSS2_RC_SUCCESS;
 
 error_cleanup:
     if (currentTime != NULL)
         SAFE_FREE(*currentTime);
+
     return r;
 }
diff --git a/src/tss2-esys/api/Esys_ReadPublic.c b/src/tss2-esys/api/Esys_ReadPublic.c
index 6f1b7bc..6f4c752 100644
--- a/src/tss2-esys/api/Esys_ReadPublic.c
+++ b/src/tss2-esys/api/Esys_ReadPublic.c
@@ -147,6 +147,7 @@
     TSS2L_SYS_AUTH_COMMAND auths;
     RSRC_NODE_T *objectHandleNode;
 
+    /* Check context, sequence correctness and set state to error for now */
     if (esysContext == NULL) {
         LOG_ERROR("esyscontext is NULL.");
         return TSS2_ESYS_RC_BAD_REFERENCE;
@@ -154,34 +155,39 @@
     r = iesys_check_sequence_async(esysContext);
     if (r != TSS2_RC_SUCCESS)
         return r;
-    r = check_session_feasability(shandle1, shandle2, shandle3, 0);
-    return_if_error(r, "Check session usage");
+    esysContext->state = _ESYS_STATE_INTERNALERROR;
 
+    /* Check and store input parameters */
+    r = check_session_feasability(shandle1, shandle2, shandle3, 0);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Check session usage");
     store_input_parameters(esysContext, objectHandle);
+
+    /* Retrieve the metadata objects for provided handles */
     r = esys_GetResourceObject(esysContext, objectHandle, &objectHandleNode);
-    if (r != TPM2_RC_SUCCESS)
-        return r;
+    return_state_if_error(r, _ESYS_STATE_INIT, "objectHandle unknown.");
+
+    /* Initial invocation of SAPI to prepare the command buffer with parameters */
     r = Tss2_Sys_ReadPublic_Prepare(esysContext->sys,
                 (objectHandleNode == NULL) ? TPM2_RH_NULL : objectHandleNode->rsrc.handle);
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error async ReadPublic");
-        return r;
-    }
+    return_state_if_error(r, _ESYS_STATE_INIT, "SAPI Prepare returned error.");
+
+    /* Calculate the cpHash Values */
     r = init_session_tab(esysContext, shandle1, shandle2, shandle3);
-    return_if_error(r, "Initialize session resources");
-
+    return_state_if_error(r, _ESYS_STATE_INIT, "Initialize session resources");
     iesys_compute_session_value(esysContext->session_tab[0], NULL, NULL);
-    r = iesys_gen_auths(esysContext, objectHandleNode, NULL, NULL, &auths);
-    return_if_error(r, "Error in computation of auth values");
+    iesys_compute_session_value(esysContext->session_tab[1], NULL, NULL);
+    iesys_compute_session_value(esysContext->session_tab[2], NULL, NULL);
 
+    /* Generate the auth values and set them in the SAPI command buffer */
+    r = iesys_gen_auths(esysContext, objectHandleNode, NULL, NULL, &auths);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Error in computation of auth values");
     esysContext->authsCount = auths.count;
     r = Tss2_Sys_SetCmdAuths(esysContext->sys, &auths);
-    if (r != TSS2_RC_SUCCESS) {
-        return r;
-    }
+    return_state_if_error(r, _ESYS_STATE_INIT, "SAPI error on SetCmdAuths");
 
+    /* Trigger execution and finish the async invocation */
     r = Tss2_Sys_ExecuteAsync(esysContext->sys);
-    return_if_error(r, "Finish (Execute Async)");
+    return_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Finish (Execute Async)");
 
     esysContext->state = _ESYS_STATE_SENT;
 
@@ -214,15 +220,20 @@
     TPM2B_NAME **qualifiedName)
 {
     LOG_TRACE("complete");
+    TSS2_RC r;
     if (esysContext == NULL) {
         LOG_ERROR("esyscontext is NULL.");
         return TSS2_ESYS_RC_BAD_REFERENCE;
     }
+
+    /* Check for correct sequence and set sequence to irregular for now */
     if (esysContext->state != _ESYS_STATE_SENT) {
         LOG_ERROR("Esys called in bad sequence.");
         return TSS2_ESYS_RC_BAD_SEQUENCE;
     }
-    TSS2_RC r;
+    esysContext->state = _ESYS_STATE_INTERNALERROR;
+
+    /* Allocate memory for response parameters */
     if (outPublic != NULL) {
         *outPublic = calloc(sizeof(TPM2B_PUBLIC), 1);
         if (*outPublic == NULL) {
@@ -241,17 +252,22 @@
             goto_error(r, TSS2_ESYS_RC_MEMORY, "Out of memory", error_cleanup);
         }
     }
+
+    /*Receive the TPM response and handle resubmissions if necessary. */
     r = Tss2_Sys_ExecuteFinish(esysContext->sys, esysContext->timeout);
     if ((r & ~TSS2_RC_LAYER_MASK) == TSS2_BASE_RC_TRY_AGAIN) {
         LOG_DEBUG("A layer below returned TRY_AGAIN: %" PRIx32, r);
+        esysContext->state = _ESYS_STATE_SENT;
         goto error_cleanup;
     }
+    /* This block handle the resubmission of TPM commands given a certain set of
+     * TPM response codes. */
     if (r == TPM2_RC_RETRY || r == TPM2_RC_TESTING || r == TPM2_RC_YIELDED) {
         LOG_DEBUG("TPM returned RETRY, TESTING or YIELDED, which triggers a "
             "resubmission: %" PRIx32, r);
         if (esysContext->submissionCount >= _ESYS_MAX_SUBMISSIONS) {
-            LOG_WARNING("Maximum number of resubmissions has been reached.");
-            esysContext->state = _ESYS_STATE_ERRORRESPONSE;
+            LOG_WARNING("Maximum number of (re)submissions has been reached.");
+            esysContext->state = _ESYS_STATE_INIT;
             goto error_cleanup;
         }
         esysContext->state = _ESYS_STATE_RESUBMISSION;
@@ -261,22 +277,32 @@
                 esysContext->session_type[1],
                 esysContext->session_type[2]);
         if (r != TSS2_RC_SUCCESS) {
-            LOG_ERROR("Error attempting to resubmit");
+            LOG_WARNING("Error attempting to resubmit");
+            /* We do not set esysContext->state here but inherit the most recent
+             * state of the _async function. */
             goto error_cleanup;
         }
         r = TSS2_ESYS_RC_TRY_AGAIN;
+        LOG_DEBUG("Resubmission initiated and returning RC_TRY_AGAIN.");
         goto error_cleanup;
     }
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error finish (ExecuteFinish) ReadPublic");
+    /* The following is the "regular error" handling. */
+    if (r != TSS2_RC_SUCCESS && (r & TSS2_RC_LAYER_MASK) == 0) {
+        LOG_WARNING("Received TPM Error");
+        esysContext->state = _ESYS_STATE_INIT;
+        goto error_cleanup;
+    } else if (r != TSS2_RC_SUCCESS) {
+        LOG_ERROR("Received a non-TPM Error");
+        esysContext->state = _ESYS_STATE_INTERNALERROR;
         goto error_cleanup;
     }
+
     /*
      * Now the verification of the response (hmac check) and if necessary the
-     * parameter decryption have to be done
+     * parameter decryption have to be done.
      */
     r = iesys_check_response(esysContext);
-    goto_if_error(r, "Error: check response",
+    goto_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Error: check response",
                       error_cleanup);
     /*
      * After the verification of the response we call the complete function
@@ -286,14 +312,15 @@
                 (outPublic != NULL) ? *outPublic : NULL,
                 (name != NULL) ? *name : NULL,
                 (qualifiedName != NULL) ? *qualifiedName : NULL);
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error finish (ExecuteFinish) ReadPublic: %" PRIx32, r);
-        esysContext->state = _ESYS_STATE_ERRORRESPONSE;
-        goto error_cleanup;;
-    }
-    esysContext->state = _ESYS_STATE_FINISHED;
+    goto_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Received error from SAPI"
+                        " unmarshalling" ,error_cleanup);
+    esysContext->state = _ESYS_STATE_INIT;
+    LOG_DEBUG("context=%p, outPublic=%p, name=%p,"
+              "qualifiedName=%p",
+              esysContext, outPublic, name,
+              qualifiedName);
 
-    return r;
+    return TSS2_RC_SUCCESS;
 
 error_cleanup:
     if (outPublic != NULL)
@@ -302,5 +329,6 @@
         SAFE_FREE(*name);
     if (qualifiedName != NULL)
         SAFE_FREE(*qualifiedName);
+
     return r;
 }
diff --git a/src/tss2-esys/api/Esys_Rewrap.c b/src/tss2-esys/api/Esys_Rewrap.c
index 9d7a26b..45933d7 100644
--- a/src/tss2-esys/api/Esys_Rewrap.c
+++ b/src/tss2-esys/api/Esys_Rewrap.c
@@ -192,6 +192,7 @@
     RSRC_NODE_T *oldParentNode;
     RSRC_NODE_T *newParentNode;
 
+    /* Check context, sequence correctness and set state to error for now */
     if (esysContext == NULL) {
         LOG_ERROR("esyscontext is NULL.");
         return TSS2_ESYS_RC_BAD_REFERENCE;
@@ -199,47 +200,49 @@
     r = iesys_check_sequence_async(esysContext);
     if (r != TSS2_RC_SUCCESS)
         return r;
-    r = check_session_feasability(shandle1, shandle2, shandle3, 1);
-    return_if_error(r, "Check session usage");
+    esysContext->state = _ESYS_STATE_INTERNALERROR;
 
+    /* Check and store input parameters */
+    r = check_session_feasability(shandle1, shandle2, shandle3, 1);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Check session usage");
     store_input_parameters(esysContext, oldParent, newParent,
                 inDuplicate,
                 name,
                 inSymSeed);
+
+    /* Retrieve the metadata objects for provided handles */
     r = esys_GetResourceObject(esysContext, oldParent, &oldParentNode);
-    if (r != TPM2_RC_SUCCESS)
-        return r;
+    return_state_if_error(r, _ESYS_STATE_INIT, "oldParent unknown.");
     r = esys_GetResourceObject(esysContext, newParent, &newParentNode);
-    if (r != TPM2_RC_SUCCESS)
-        return r;
+    return_state_if_error(r, _ESYS_STATE_INIT, "newParent unknown.");
+
+    /* Initial invocation of SAPI to prepare the command buffer with parameters */
     r = Tss2_Sys_Rewrap_Prepare(esysContext->sys,
                 (oldParentNode == NULL) ? TPM2_RH_NULL : oldParentNode->rsrc.handle,
                 (newParentNode == NULL) ? TPM2_RH_NULL : newParentNode->rsrc.handle,
                 inDuplicate,
                 name,
                 inSymSeed);
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error async Rewrap");
-        return r;
-    }
-    r = init_session_tab(esysContext, shandle1, shandle2, shandle3);
-    return_if_error(r, "Initialize session resources");
+    return_state_if_error(r, _ESYS_STATE_INIT, "SAPI Prepare returned error.");
 
+    /* Calculate the cpHash Values */
+    r = init_session_tab(esysContext, shandle1, shandle2, shandle3);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Initialize session resources");
     iesys_compute_session_value(esysContext->session_tab[0],
                 &oldParentNode->rsrc.name, &oldParentNode->auth);
     iesys_compute_session_value(esysContext->session_tab[1], NULL, NULL);
     iesys_compute_session_value(esysContext->session_tab[2], NULL, NULL);
-    r = iesys_gen_auths(esysContext, oldParentNode, newParentNode, NULL, &auths);
-    return_if_error(r, "Error in computation of auth values");
 
+    /* Generate the auth values and set them in the SAPI command buffer */
+    r = iesys_gen_auths(esysContext, oldParentNode, newParentNode, NULL, &auths);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Error in computation of auth values");
     esysContext->authsCount = auths.count;
     r = Tss2_Sys_SetCmdAuths(esysContext->sys, &auths);
-    if (r != TSS2_RC_SUCCESS) {
-        return r;
-    }
+    return_state_if_error(r, _ESYS_STATE_INIT, "SAPI error on SetCmdAuths");
 
+    /* Trigger execution and finish the async invocation */
     r = Tss2_Sys_ExecuteAsync(esysContext->sys);
-    return_if_error(r, "Finish (Execute Async)");
+    return_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Finish (Execute Async)");
 
     esysContext->state = _ESYS_STATE_SENT;
 
@@ -269,15 +272,20 @@
     TPM2B_ENCRYPTED_SECRET **outSymSeed)
 {
     LOG_TRACE("complete");
+    TSS2_RC r;
     if (esysContext == NULL) {
         LOG_ERROR("esyscontext is NULL.");
         return TSS2_ESYS_RC_BAD_REFERENCE;
     }
+
+    /* Check for correct sequence and set sequence to irregular for now */
     if (esysContext->state != _ESYS_STATE_SENT) {
         LOG_ERROR("Esys called in bad sequence.");
         return TSS2_ESYS_RC_BAD_SEQUENCE;
     }
-    TSS2_RC r;
+    esysContext->state = _ESYS_STATE_INTERNALERROR;
+
+    /* Allocate memory for response parameters */
     if (outDuplicate != NULL) {
         *outDuplicate = calloc(sizeof(TPM2B_PRIVATE), 1);
         if (*outDuplicate == NULL) {
@@ -290,17 +298,22 @@
             goto_error(r, TSS2_ESYS_RC_MEMORY, "Out of memory", error_cleanup);
         }
     }
+
+    /*Receive the TPM response and handle resubmissions if necessary. */
     r = Tss2_Sys_ExecuteFinish(esysContext->sys, esysContext->timeout);
     if ((r & ~TSS2_RC_LAYER_MASK) == TSS2_BASE_RC_TRY_AGAIN) {
         LOG_DEBUG("A layer below returned TRY_AGAIN: %" PRIx32, r);
+        esysContext->state = _ESYS_STATE_SENT;
         goto error_cleanup;
     }
+    /* This block handle the resubmission of TPM commands given a certain set of
+     * TPM response codes. */
     if (r == TPM2_RC_RETRY || r == TPM2_RC_TESTING || r == TPM2_RC_YIELDED) {
         LOG_DEBUG("TPM returned RETRY, TESTING or YIELDED, which triggers a "
             "resubmission: %" PRIx32, r);
         if (esysContext->submissionCount >= _ESYS_MAX_SUBMISSIONS) {
-            LOG_WARNING("Maximum number of resubmissions has been reached.");
-            esysContext->state = _ESYS_STATE_ERRORRESPONSE;
+            LOG_WARNING("Maximum number of (re)submissions has been reached.");
+            esysContext->state = _ESYS_STATE_INIT;
             goto error_cleanup;
         }
         esysContext->state = _ESYS_STATE_RESUBMISSION;
@@ -314,22 +327,32 @@
                 esysContext->in.Rewrap.name,
                 esysContext->in.Rewrap.inSymSeed);
         if (r != TSS2_RC_SUCCESS) {
-            LOG_ERROR("Error attempting to resubmit");
+            LOG_WARNING("Error attempting to resubmit");
+            /* We do not set esysContext->state here but inherit the most recent
+             * state of the _async function. */
             goto error_cleanup;
         }
         r = TSS2_ESYS_RC_TRY_AGAIN;
+        LOG_DEBUG("Resubmission initiated and returning RC_TRY_AGAIN.");
         goto error_cleanup;
     }
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error finish (ExecuteFinish) Rewrap");
+    /* The following is the "regular error" handling. */
+    if (r != TSS2_RC_SUCCESS && (r & TSS2_RC_LAYER_MASK) == 0) {
+        LOG_WARNING("Received TPM Error");
+        esysContext->state = _ESYS_STATE_INIT;
+        goto error_cleanup;
+    } else if (r != TSS2_RC_SUCCESS) {
+        LOG_ERROR("Received a non-TPM Error");
+        esysContext->state = _ESYS_STATE_INTERNALERROR;
         goto error_cleanup;
     }
+
     /*
      * Now the verification of the response (hmac check) and if necessary the
-     * parameter decryption have to be done
+     * parameter decryption have to be done.
      */
     r = iesys_check_response(esysContext);
-    goto_if_error(r, "Error: check response",
+    goto_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Error: check response",
                       error_cleanup);
     /*
      * After the verification of the response we call the complete function
@@ -338,19 +361,19 @@
     r = Tss2_Sys_Rewrap_Complete(esysContext->sys,
                 (outDuplicate != NULL) ? *outDuplicate : NULL,
                 (outSymSeed != NULL) ? *outSymSeed : NULL);
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error finish (ExecuteFinish) Rewrap: %" PRIx32, r);
-        esysContext->state = _ESYS_STATE_ERRORRESPONSE;
-        goto error_cleanup;;
-    }
-    esysContext->state = _ESYS_STATE_FINISHED;
+    goto_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Received error from SAPI"
+                        " unmarshalling" ,error_cleanup);
+    esysContext->state = _ESYS_STATE_INIT;
+    LOG_DEBUG("context=%p, outDuplicate=%p, outSymSeed=%p",
+              esysContext, outDuplicate, outSymSeed);
 
-    return r;
+    return TSS2_RC_SUCCESS;
 
 error_cleanup:
     if (outDuplicate != NULL)
         SAFE_FREE(*outDuplicate);
     if (outSymSeed != NULL)
         SAFE_FREE(*outSymSeed);
+
     return r;
 }
diff --git a/src/tss2-esys/api/Esys_SelfTest.c b/src/tss2-esys/api/Esys_SelfTest.c
index 2b85c79..bec6f76 100644
--- a/src/tss2-esys/api/Esys_SelfTest.c
+++ b/src/tss2-esys/api/Esys_SelfTest.c
@@ -132,6 +132,7 @@
     TSS2_RC r;
     TSS2L_SYS_AUTH_COMMAND auths;
 
+    /* Check context, sequence correctness and set state to error for now */
     if (esysContext == NULL) {
         LOG_ERROR("esyscontext is NULL.");
         return TSS2_ESYS_RC_BAD_REFERENCE;
@@ -139,32 +140,36 @@
     r = iesys_check_sequence_async(esysContext);
     if (r != TSS2_RC_SUCCESS)
         return r;
-    r = check_session_feasability(shandle1, shandle2, shandle3, 0);
-    return_if_error(r, "Check session usage");
+    esysContext->state = _ESYS_STATE_INTERNALERROR;
 
+    /* Check and store input parameters */
+    r = check_session_feasability(shandle1, shandle2, shandle3, 0);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Check session usage");
     store_input_parameters(esysContext,
                 fullTest);
+
+    /* Initial invocation of SAPI to prepare the command buffer with parameters */
     r = Tss2_Sys_SelfTest_Prepare(esysContext->sys,
                 fullTest);
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error async SelfTest");
-        return r;
-    }
+    return_state_if_error(r, _ESYS_STATE_INIT, "SAPI Prepare returned error.");
+
+    /* Calculate the cpHash Values */
     r = init_session_tab(esysContext, shandle1, shandle2, shandle3);
-    return_if_error(r, "Initialize session resources");
-
+    return_state_if_error(r, _ESYS_STATE_INIT, "Initialize session resources");
     iesys_compute_session_value(esysContext->session_tab[0], NULL, NULL);
-    r = iesys_gen_auths(esysContext, NULL, NULL, NULL, &auths);
-    return_if_error(r, "Error in computation of auth values");
+    iesys_compute_session_value(esysContext->session_tab[1], NULL, NULL);
+    iesys_compute_session_value(esysContext->session_tab[2], NULL, NULL);
 
+    /* Generate the auth values and set them in the SAPI command buffer */
+    r = iesys_gen_auths(esysContext, NULL, NULL, NULL, &auths);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Error in computation of auth values");
     esysContext->authsCount = auths.count;
     r = Tss2_Sys_SetCmdAuths(esysContext->sys, &auths);
-    if (r != TSS2_RC_SUCCESS) {
-        return r;
-    }
+    return_state_if_error(r, _ESYS_STATE_INIT, "SAPI error on SetCmdAuths");
 
+    /* Trigger execution and finish the async invocation */
     r = Tss2_Sys_ExecuteAsync(esysContext->sys);
-    return_if_error(r, "Finish (Execute Async)");
+    return_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Finish (Execute Async)");
 
     esysContext->state = _ESYS_STATE_SENT;
 
@@ -188,26 +193,34 @@
     ESYS_CONTEXT *esysContext)
 {
     LOG_TRACE("complete");
+    TSS2_RC r;
     if (esysContext == NULL) {
         LOG_ERROR("esyscontext is NULL.");
         return TSS2_ESYS_RC_BAD_REFERENCE;
     }
+
+    /* Check for correct sequence and set sequence to irregular for now */
     if (esysContext->state != _ESYS_STATE_SENT) {
         LOG_ERROR("Esys called in bad sequence.");
         return TSS2_ESYS_RC_BAD_SEQUENCE;
     }
-    TSS2_RC r;
+    esysContext->state = _ESYS_STATE_INTERNALERROR;
+
+    /*Receive the TPM response and handle resubmissions if necessary. */
     r = Tss2_Sys_ExecuteFinish(esysContext->sys, esysContext->timeout);
     if ((r & ~TSS2_RC_LAYER_MASK) == TSS2_BASE_RC_TRY_AGAIN) {
         LOG_DEBUG("A layer below returned TRY_AGAIN: %" PRIx32, r);
+        esysContext->state = _ESYS_STATE_SENT;
         return r;
     }
+    /* This block handle the resubmission of TPM commands given a certain set of
+     * TPM response codes. */
     if (r == TPM2_RC_RETRY || r == TPM2_RC_TESTING || r == TPM2_RC_YIELDED) {
         LOG_DEBUG("TPM returned RETRY, TESTING or YIELDED, which triggers a "
             "resubmission: %" PRIx32, r);
         if (esysContext->submissionCount >= _ESYS_MAX_SUBMISSIONS) {
-            LOG_WARNING("Maximum number of resubmissions has been reached.");
-            esysContext->state = _ESYS_STATE_ERRORRESPONSE;
+            LOG_WARNING("Maximum number of (re)submissions has been reached.");
+            esysContext->state = _ESYS_STATE_INIT;
             return r;
         }
         esysContext->state = _ESYS_STATE_RESUBMISSION;
@@ -217,33 +230,42 @@
                 esysContext->session_type[2],
                 esysContext->in.SelfTest.fullTest);
         if (r != TSS2_RC_SUCCESS) {
-            LOG_ERROR("Error attempting to resubmit");
+            LOG_WARNING("Error attempting to resubmit");
+            /* We do not set esysContext->state here but inherit the most recent
+             * state of the _async function. */
             return r;
         }
         r = TSS2_ESYS_RC_TRY_AGAIN;
+        LOG_DEBUG("Resubmission initiated and returning RC_TRY_AGAIN.");
         return r;
     }
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error finish (ExecuteFinish) SelfTest");
+    /* The following is the "regular error" handling. */
+    if (r != TSS2_RC_SUCCESS && (r & TSS2_RC_LAYER_MASK) == 0) {
+        LOG_WARNING("Received TPM Error");
+        esysContext->state = _ESYS_STATE_INIT;
+        return r;
+    } else if (r != TSS2_RC_SUCCESS) {
+        LOG_ERROR("Received a non-TPM Error");
+        esysContext->state = _ESYS_STATE_INTERNALERROR;
         return r;
     }
+
     /*
      * Now the verification of the response (hmac check) and if necessary the
-     * parameter decryption have to be done
+     * parameter decryption have to be done.
      */
     r = iesys_check_response(esysContext);
-    return_if_error(r, "Error: check response");
+    return_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Error: check response");
     /*
      * After the verification of the response we call the complete function
      * to deliver the result.
      */
     r = Tss2_Sys_SelfTest_Complete(esysContext->sys);
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error finish (ExecuteFinish) SelfTest: %" PRIx32, r);
-        esysContext->state = _ESYS_STATE_ERRORRESPONSE;
-        return r;;
-    }
-    esysContext->state = _ESYS_STATE_FINISHED;
+    return_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Received error from SAPI"
+                        " unmarshalling" );
+    esysContext->state = _ESYS_STATE_INIT;
+    LOG_DEBUG("context=%p",
+              esysContext);
 
-    return r;
+    return TSS2_RC_SUCCESS;
 }
diff --git a/src/tss2-esys/api/Esys_SequenceComplete.c b/src/tss2-esys/api/Esys_SequenceComplete.c
index 9a0bb0a..4014448 100644
--- a/src/tss2-esys/api/Esys_SequenceComplete.c
+++ b/src/tss2-esys/api/Esys_SequenceComplete.c
@@ -163,6 +163,7 @@
     TSS2L_SYS_AUTH_COMMAND auths;
     RSRC_NODE_T *sequenceHandleNode;
 
+    /* Check context, sequence correctness and set state to error for now */
     if (esysContext == NULL) {
         LOG_ERROR("esyscontext is NULL.");
         return TSS2_ESYS_RC_BAD_REFERENCE;
@@ -170,41 +171,44 @@
     r = iesys_check_sequence_async(esysContext);
     if (r != TSS2_RC_SUCCESS)
         return r;
-    r = check_session_feasability(shandle1, shandle2, shandle3, 1);
-    return_if_error(r, "Check session usage");
+    esysContext->state = _ESYS_STATE_INTERNALERROR;
 
+    /* Check and store input parameters */
+    r = check_session_feasability(shandle1, shandle2, shandle3, 1);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Check session usage");
     store_input_parameters(esysContext, sequenceHandle,
                 buffer,
                 hierarchy);
+
+    /* Retrieve the metadata objects for provided handles */
     r = esys_GetResourceObject(esysContext, sequenceHandle, &sequenceHandleNode);
-    if (r != TPM2_RC_SUCCESS)
-        return r;
+    return_state_if_error(r, _ESYS_STATE_INIT, "sequenceHandle unknown.");
+
+    /* Initial invocation of SAPI to prepare the command buffer with parameters */
     r = Tss2_Sys_SequenceComplete_Prepare(esysContext->sys,
                 (sequenceHandleNode == NULL) ? TPM2_RH_NULL : sequenceHandleNode->rsrc.handle,
                 buffer,
                 hierarchy);
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error async SequenceComplete");
-        return r;
-    }
-    r = init_session_tab(esysContext, shandle1, shandle2, shandle3);
-    return_if_error(r, "Initialize session resources");
+    return_state_if_error(r, _ESYS_STATE_INIT, "SAPI Prepare returned error.");
 
+    /* Calculate the cpHash Values */
+    r = init_session_tab(esysContext, shandle1, shandle2, shandle3);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Initialize session resources");
     iesys_compute_session_value(esysContext->session_tab[0],
                 &sequenceHandleNode->rsrc.name, &sequenceHandleNode->auth);
     iesys_compute_session_value(esysContext->session_tab[1], NULL, NULL);
     iesys_compute_session_value(esysContext->session_tab[2], NULL, NULL);
-    r = iesys_gen_auths(esysContext, sequenceHandleNode, NULL, NULL, &auths);
-    return_if_error(r, "Error in computation of auth values");
 
+    /* Generate the auth values and set them in the SAPI command buffer */
+    r = iesys_gen_auths(esysContext, sequenceHandleNode, NULL, NULL, &auths);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Error in computation of auth values");
     esysContext->authsCount = auths.count;
     r = Tss2_Sys_SetCmdAuths(esysContext->sys, &auths);
-    if (r != TSS2_RC_SUCCESS) {
-        return r;
-    }
+    return_state_if_error(r, _ESYS_STATE_INIT, "SAPI error on SetCmdAuths");
 
+    /* Trigger execution and finish the async invocation */
     r = Tss2_Sys_ExecuteAsync(esysContext->sys);
-    return_if_error(r, "Finish (Execute Async)");
+    return_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Finish (Execute Async)");
 
     esysContext->state = _ESYS_STATE_SENT;
 
@@ -234,15 +238,20 @@
     TPMT_TK_HASHCHECK **validation)
 {
     LOG_TRACE("complete");
+    TSS2_RC r;
     if (esysContext == NULL) {
         LOG_ERROR("esyscontext is NULL.");
         return TSS2_ESYS_RC_BAD_REFERENCE;
     }
+
+    /* Check for correct sequence and set sequence to irregular for now */
     if (esysContext->state != _ESYS_STATE_SENT) {
         LOG_ERROR("Esys called in bad sequence.");
         return TSS2_ESYS_RC_BAD_SEQUENCE;
     }
-    TSS2_RC r;
+    esysContext->state = _ESYS_STATE_INTERNALERROR;
+
+    /* Allocate memory for response parameters */
     if (result != NULL) {
         *result = calloc(sizeof(TPM2B_DIGEST), 1);
         if (*result == NULL) {
@@ -255,17 +264,22 @@
             goto_error(r, TSS2_ESYS_RC_MEMORY, "Out of memory", error_cleanup);
         }
     }
+
+    /*Receive the TPM response and handle resubmissions if necessary. */
     r = Tss2_Sys_ExecuteFinish(esysContext->sys, esysContext->timeout);
     if ((r & ~TSS2_RC_LAYER_MASK) == TSS2_BASE_RC_TRY_AGAIN) {
         LOG_DEBUG("A layer below returned TRY_AGAIN: %" PRIx32, r);
+        esysContext->state = _ESYS_STATE_SENT;
         goto error_cleanup;
     }
+    /* This block handle the resubmission of TPM commands given a certain set of
+     * TPM response codes. */
     if (r == TPM2_RC_RETRY || r == TPM2_RC_TESTING || r == TPM2_RC_YIELDED) {
         LOG_DEBUG("TPM returned RETRY, TESTING or YIELDED, which triggers a "
             "resubmission: %" PRIx32, r);
         if (esysContext->submissionCount >= _ESYS_MAX_SUBMISSIONS) {
-            LOG_WARNING("Maximum number of resubmissions has been reached.");
-            esysContext->state = _ESYS_STATE_ERRORRESPONSE;
+            LOG_WARNING("Maximum number of (re)submissions has been reached.");
+            esysContext->state = _ESYS_STATE_INIT;
             goto error_cleanup;
         }
         esysContext->state = _ESYS_STATE_RESUBMISSION;
@@ -277,22 +291,32 @@
                 esysContext->in.SequenceComplete.buffer,
                 esysContext->in.SequenceComplete.hierarchy);
         if (r != TSS2_RC_SUCCESS) {
-            LOG_ERROR("Error attempting to resubmit");
+            LOG_WARNING("Error attempting to resubmit");
+            /* We do not set esysContext->state here but inherit the most recent
+             * state of the _async function. */
             goto error_cleanup;
         }
         r = TSS2_ESYS_RC_TRY_AGAIN;
+        LOG_DEBUG("Resubmission initiated and returning RC_TRY_AGAIN.");
         goto error_cleanup;
     }
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error finish (ExecuteFinish) SequenceComplete");
+    /* The following is the "regular error" handling. */
+    if (r != TSS2_RC_SUCCESS && (r & TSS2_RC_LAYER_MASK) == 0) {
+        LOG_WARNING("Received TPM Error");
+        esysContext->state = _ESYS_STATE_INIT;
+        goto error_cleanup;
+    } else if (r != TSS2_RC_SUCCESS) {
+        LOG_ERROR("Received a non-TPM Error");
+        esysContext->state = _ESYS_STATE_INTERNALERROR;
         goto error_cleanup;
     }
+
     /*
      * Now the verification of the response (hmac check) and if necessary the
-     * parameter decryption have to be done
+     * parameter decryption have to be done.
      */
     r = iesys_check_response(esysContext);
-    goto_if_error(r, "Error: check response",
+    goto_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Error: check response",
                       error_cleanup);
     /*
      * After the verification of the response we call the complete function
@@ -301,23 +325,23 @@
     r = Tss2_Sys_SequenceComplete_Complete(esysContext->sys,
                 (result != NULL) ? *result : NULL,
                 (validation != NULL) ? *validation : NULL);
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error finish (ExecuteFinish) SequenceComplete: %" PRIx32, r);
-        esysContext->state = _ESYS_STATE_ERRORRESPONSE;
-        goto error_cleanup;;
-    }
+    goto_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Received error from SAPI"
+                        " unmarshalling" ,error_cleanup);
     /* The ESYS_TR sequence object has to be invalidated */
     r = Esys_TR_Close(esysContext, &esysContext->in.SequenceComplete.sequenceHandle);
     goto_if_error(r, "invalidate object", error_cleanup);
 
-    esysContext->state = _ESYS_STATE_FINISHED;
+    esysContext->state = _ESYS_STATE_INIT;
+    LOG_DEBUG("context=%p, result=%p, validation=%p",
+              esysContext, result, validation);
 
-    return r;
+    return TSS2_RC_SUCCESS;
 
 error_cleanup:
     if (result != NULL)
         SAFE_FREE(*result);
     if (validation != NULL)
         SAFE_FREE(*validation);
+
     return r;
 }
diff --git a/src/tss2-esys/api/Esys_SequenceUpdate.c b/src/tss2-esys/api/Esys_SequenceUpdate.c
index fffc11b..3ed4dc6 100644
--- a/src/tss2-esys/api/Esys_SequenceUpdate.c
+++ b/src/tss2-esys/api/Esys_SequenceUpdate.c
@@ -148,6 +148,7 @@
     TSS2L_SYS_AUTH_COMMAND auths;
     RSRC_NODE_T *sequenceHandleNode;
 
+    /* Check context, sequence correctness and set state to error for now */
     if (esysContext == NULL) {
         LOG_ERROR("esyscontext is NULL.");
         return TSS2_ESYS_RC_BAD_REFERENCE;
@@ -155,38 +156,42 @@
     r = iesys_check_sequence_async(esysContext);
     if (r != TSS2_RC_SUCCESS)
         return r;
-    r = check_session_feasability(shandle1, shandle2, shandle3, 1);
-    return_if_error(r, "Check session usage");
+    esysContext->state = _ESYS_STATE_INTERNALERROR;
 
+    /* Check and store input parameters */
+    r = check_session_feasability(shandle1, shandle2, shandle3, 1);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Check session usage");
     store_input_parameters(esysContext, sequenceHandle,
                 buffer);
+
+    /* Retrieve the metadata objects for provided handles */
     r = esys_GetResourceObject(esysContext, sequenceHandle, &sequenceHandleNode);
-    if (r != TPM2_RC_SUCCESS)
-        return r;
+    return_state_if_error(r, _ESYS_STATE_INIT, "sequenceHandle unknown.");
+
+    /* Initial invocation of SAPI to prepare the command buffer with parameters */
     r = Tss2_Sys_SequenceUpdate_Prepare(esysContext->sys,
                 (sequenceHandleNode == NULL) ? TPM2_RH_NULL : sequenceHandleNode->rsrc.handle,
                 buffer);
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error async SequenceUpdate");
-        return r;
-    }
-    r = init_session_tab(esysContext, shandle1, shandle2, shandle3);
-    return_if_error(r, "Initialize session resources");
+    return_state_if_error(r, _ESYS_STATE_INIT, "SAPI Prepare returned error.");
 
+    /* Calculate the cpHash Values */
+    r = init_session_tab(esysContext, shandle1, shandle2, shandle3);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Initialize session resources");
     iesys_compute_session_value(esysContext->session_tab[0],
                 &sequenceHandleNode->rsrc.name, &sequenceHandleNode->auth);
     iesys_compute_session_value(esysContext->session_tab[1], NULL, NULL);
-    r = iesys_gen_auths(esysContext, sequenceHandleNode, NULL, NULL, &auths);
-    return_if_error(r, "Error in computation of auth values");
+    iesys_compute_session_value(esysContext->session_tab[2], NULL, NULL);
 
+    /* Generate the auth values and set them in the SAPI command buffer */
+    r = iesys_gen_auths(esysContext, sequenceHandleNode, NULL, NULL, &auths);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Error in computation of auth values");
     esysContext->authsCount = auths.count;
     r = Tss2_Sys_SetCmdAuths(esysContext->sys, &auths);
-    if (r != TSS2_RC_SUCCESS) {
-        return r;
-    }
+    return_state_if_error(r, _ESYS_STATE_INIT, "SAPI error on SetCmdAuths");
 
+    /* Trigger execution and finish the async invocation */
     r = Tss2_Sys_ExecuteAsync(esysContext->sys);
-    return_if_error(r, "Finish (Execute Async)");
+    return_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Finish (Execute Async)");
 
     esysContext->state = _ESYS_STATE_SENT;
 
@@ -210,26 +215,34 @@
     ESYS_CONTEXT *esysContext)
 {
     LOG_TRACE("complete");
+    TSS2_RC r;
     if (esysContext == NULL) {
         LOG_ERROR("esyscontext is NULL.");
         return TSS2_ESYS_RC_BAD_REFERENCE;
     }
+
+    /* Check for correct sequence and set sequence to irregular for now */
     if (esysContext->state != _ESYS_STATE_SENT) {
         LOG_ERROR("Esys called in bad sequence.");
         return TSS2_ESYS_RC_BAD_SEQUENCE;
     }
-    TSS2_RC r;
+    esysContext->state = _ESYS_STATE_INTERNALERROR;
+
+    /*Receive the TPM response and handle resubmissions if necessary. */
     r = Tss2_Sys_ExecuteFinish(esysContext->sys, esysContext->timeout);
     if ((r & ~TSS2_RC_LAYER_MASK) == TSS2_BASE_RC_TRY_AGAIN) {
         LOG_DEBUG("A layer below returned TRY_AGAIN: %" PRIx32, r);
+        esysContext->state = _ESYS_STATE_SENT;
         return r;
     }
+    /* This block handle the resubmission of TPM commands given a certain set of
+     * TPM response codes. */
     if (r == TPM2_RC_RETRY || r == TPM2_RC_TESTING || r == TPM2_RC_YIELDED) {
         LOG_DEBUG("TPM returned RETRY, TESTING or YIELDED, which triggers a "
             "resubmission: %" PRIx32, r);
         if (esysContext->submissionCount >= _ESYS_MAX_SUBMISSIONS) {
-            LOG_WARNING("Maximum number of resubmissions has been reached.");
-            esysContext->state = _ESYS_STATE_ERRORRESPONSE;
+            LOG_WARNING("Maximum number of (re)submissions has been reached.");
+            esysContext->state = _ESYS_STATE_INIT;
             return r;
         }
         esysContext->state = _ESYS_STATE_RESUBMISSION;
@@ -240,33 +253,42 @@
                 esysContext->session_type[2],
                 esysContext->in.SequenceUpdate.buffer);
         if (r != TSS2_RC_SUCCESS) {
-            LOG_ERROR("Error attempting to resubmit");
+            LOG_WARNING("Error attempting to resubmit");
+            /* We do not set esysContext->state here but inherit the most recent
+             * state of the _async function. */
             return r;
         }
         r = TSS2_ESYS_RC_TRY_AGAIN;
+        LOG_DEBUG("Resubmission initiated and returning RC_TRY_AGAIN.");
         return r;
     }
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error finish (ExecuteFinish) SequenceUpdate");
+    /* The following is the "regular error" handling. */
+    if (r != TSS2_RC_SUCCESS && (r & TSS2_RC_LAYER_MASK) == 0) {
+        LOG_WARNING("Received TPM Error");
+        esysContext->state = _ESYS_STATE_INIT;
+        return r;
+    } else if (r != TSS2_RC_SUCCESS) {
+        LOG_ERROR("Received a non-TPM Error");
+        esysContext->state = _ESYS_STATE_INTERNALERROR;
         return r;
     }
+
     /*
      * Now the verification of the response (hmac check) and if necessary the
-     * parameter decryption have to be done
+     * parameter decryption have to be done.
      */
     r = iesys_check_response(esysContext);
-    return_if_error(r, "Error: check response");
+    return_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Error: check response");
     /*
      * After the verification of the response we call the complete function
      * to deliver the result.
      */
     r = Tss2_Sys_SequenceUpdate_Complete(esysContext->sys);
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error finish (ExecuteFinish) SequenceUpdate: %" PRIx32, r);
-        esysContext->state = _ESYS_STATE_ERRORRESPONSE;
-        return r;;
-    }
-    esysContext->state = _ESYS_STATE_FINISHED;
+    return_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Received error from SAPI"
+                        " unmarshalling" );
+    esysContext->state = _ESYS_STATE_INIT;
+    LOG_DEBUG("context=%p",
+              esysContext);
 
-    return r;
+    return TSS2_RC_SUCCESS;
 }
diff --git a/src/tss2-esys/api/Esys_SetAlgorithmSet.c b/src/tss2-esys/api/Esys_SetAlgorithmSet.c
index 4126ed4..c73363b 100644
--- a/src/tss2-esys/api/Esys_SetAlgorithmSet.c
+++ b/src/tss2-esys/api/Esys_SetAlgorithmSet.c
@@ -142,6 +142,7 @@
     TSS2L_SYS_AUTH_COMMAND auths;
     RSRC_NODE_T *authHandleNode;
 
+    /* Check context, sequence correctness and set state to error for now */
     if (esysContext == NULL) {
         LOG_ERROR("esyscontext is NULL.");
         return TSS2_ESYS_RC_BAD_REFERENCE;
@@ -149,38 +150,42 @@
     r = iesys_check_sequence_async(esysContext);
     if (r != TSS2_RC_SUCCESS)
         return r;
-    r = check_session_feasability(shandle1, shandle2, shandle3, 1);
-    return_if_error(r, "Check session usage");
+    esysContext->state = _ESYS_STATE_INTERNALERROR;
 
+    /* Check and store input parameters */
+    r = check_session_feasability(shandle1, shandle2, shandle3, 1);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Check session usage");
     store_input_parameters(esysContext, authHandle,
                 algorithmSet);
+
+    /* Retrieve the metadata objects for provided handles */
     r = esys_GetResourceObject(esysContext, authHandle, &authHandleNode);
-    if (r != TPM2_RC_SUCCESS)
-        return r;
+    return_state_if_error(r, _ESYS_STATE_INIT, "authHandle unknown.");
+
+    /* Initial invocation of SAPI to prepare the command buffer with parameters */
     r = Tss2_Sys_SetAlgorithmSet_Prepare(esysContext->sys,
                 (authHandleNode == NULL) ? TPM2_RH_NULL : authHandleNode->rsrc.handle,
                 algorithmSet);
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error async SetAlgorithmSet");
-        return r;
-    }
-    r = init_session_tab(esysContext, shandle1, shandle2, shandle3);
-    return_if_error(r, "Initialize session resources");
+    return_state_if_error(r, _ESYS_STATE_INIT, "SAPI Prepare returned error.");
 
+    /* Calculate the cpHash Values */
+    r = init_session_tab(esysContext, shandle1, shandle2, shandle3);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Initialize session resources");
     iesys_compute_session_value(esysContext->session_tab[0],
                 &authHandleNode->rsrc.name, &authHandleNode->auth);
     iesys_compute_session_value(esysContext->session_tab[1], NULL, NULL);
-    r = iesys_gen_auths(esysContext, authHandleNode, NULL, NULL, &auths);
-    return_if_error(r, "Error in computation of auth values");
+    iesys_compute_session_value(esysContext->session_tab[2], NULL, NULL);
 
+    /* Generate the auth values and set them in the SAPI command buffer */
+    r = iesys_gen_auths(esysContext, authHandleNode, NULL, NULL, &auths);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Error in computation of auth values");
     esysContext->authsCount = auths.count;
     r = Tss2_Sys_SetCmdAuths(esysContext->sys, &auths);
-    if (r != TSS2_RC_SUCCESS) {
-        return r;
-    }
+    return_state_if_error(r, _ESYS_STATE_INIT, "SAPI error on SetCmdAuths");
 
+    /* Trigger execution and finish the async invocation */
     r = Tss2_Sys_ExecuteAsync(esysContext->sys);
-    return_if_error(r, "Finish (Execute Async)");
+    return_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Finish (Execute Async)");
 
     esysContext->state = _ESYS_STATE_SENT;
 
@@ -204,26 +209,34 @@
     ESYS_CONTEXT *esysContext)
 {
     LOG_TRACE("complete");
+    TSS2_RC r;
     if (esysContext == NULL) {
         LOG_ERROR("esyscontext is NULL.");
         return TSS2_ESYS_RC_BAD_REFERENCE;
     }
+
+    /* Check for correct sequence and set sequence to irregular for now */
     if (esysContext->state != _ESYS_STATE_SENT) {
         LOG_ERROR("Esys called in bad sequence.");
         return TSS2_ESYS_RC_BAD_SEQUENCE;
     }
-    TSS2_RC r;
+    esysContext->state = _ESYS_STATE_INTERNALERROR;
+
+    /*Receive the TPM response and handle resubmissions if necessary. */
     r = Tss2_Sys_ExecuteFinish(esysContext->sys, esysContext->timeout);
     if ((r & ~TSS2_RC_LAYER_MASK) == TSS2_BASE_RC_TRY_AGAIN) {
         LOG_DEBUG("A layer below returned TRY_AGAIN: %" PRIx32, r);
+        esysContext->state = _ESYS_STATE_SENT;
         return r;
     }
+    /* This block handle the resubmission of TPM commands given a certain set of
+     * TPM response codes. */
     if (r == TPM2_RC_RETRY || r == TPM2_RC_TESTING || r == TPM2_RC_YIELDED) {
         LOG_DEBUG("TPM returned RETRY, TESTING or YIELDED, which triggers a "
             "resubmission: %" PRIx32, r);
         if (esysContext->submissionCount >= _ESYS_MAX_SUBMISSIONS) {
-            LOG_WARNING("Maximum number of resubmissions has been reached.");
-            esysContext->state = _ESYS_STATE_ERRORRESPONSE;
+            LOG_WARNING("Maximum number of (re)submissions has been reached.");
+            esysContext->state = _ESYS_STATE_INIT;
             return r;
         }
         esysContext->state = _ESYS_STATE_RESUBMISSION;
@@ -234,33 +247,42 @@
                 esysContext->session_type[2],
                 esysContext->in.SetAlgorithmSet.algorithmSet);
         if (r != TSS2_RC_SUCCESS) {
-            LOG_ERROR("Error attempting to resubmit");
+            LOG_WARNING("Error attempting to resubmit");
+            /* We do not set esysContext->state here but inherit the most recent
+             * state of the _async function. */
             return r;
         }
         r = TSS2_ESYS_RC_TRY_AGAIN;
+        LOG_DEBUG("Resubmission initiated and returning RC_TRY_AGAIN.");
         return r;
     }
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error finish (ExecuteFinish) SetAlgorithmSet");
+    /* The following is the "regular error" handling. */
+    if (r != TSS2_RC_SUCCESS && (r & TSS2_RC_LAYER_MASK) == 0) {
+        LOG_WARNING("Received TPM Error");
+        esysContext->state = _ESYS_STATE_INIT;
+        return r;
+    } else if (r != TSS2_RC_SUCCESS) {
+        LOG_ERROR("Received a non-TPM Error");
+        esysContext->state = _ESYS_STATE_INTERNALERROR;
         return r;
     }
+
     /*
      * Now the verification of the response (hmac check) and if necessary the
-     * parameter decryption have to be done
+     * parameter decryption have to be done.
      */
     r = iesys_check_response(esysContext);
-    return_if_error(r, "Error: check response");
+    return_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Error: check response");
     /*
      * After the verification of the response we call the complete function
      * to deliver the result.
      */
     r = Tss2_Sys_SetAlgorithmSet_Complete(esysContext->sys);
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error finish (ExecuteFinish) SetAlgorithmSet: %" PRIx32, r);
-        esysContext->state = _ESYS_STATE_ERRORRESPONSE;
-        return r;;
-    }
-    esysContext->state = _ESYS_STATE_FINISHED;
+    return_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Received error from SAPI"
+                        " unmarshalling" );
+    esysContext->state = _ESYS_STATE_INIT;
+    LOG_DEBUG("context=%p",
+              esysContext);
 
-    return r;
+    return TSS2_RC_SUCCESS;
 }
diff --git a/src/tss2-esys/api/Esys_SetCommandCodeAuditStatus.c b/src/tss2-esys/api/Esys_SetCommandCodeAuditStatus.c
index d5d56a0..9f4279a 100644
--- a/src/tss2-esys/api/Esys_SetCommandCodeAuditStatus.c
+++ b/src/tss2-esys/api/Esys_SetCommandCodeAuditStatus.c
@@ -168,6 +168,7 @@
     TSS2L_SYS_AUTH_COMMAND auths;
     RSRC_NODE_T *authNode;
 
+    /* Check context, sequence correctness and set state to error for now */
     if (esysContext == NULL) {
         LOG_ERROR("esyscontext is NULL.");
         return TSS2_ESYS_RC_BAD_REFERENCE;
@@ -175,43 +176,46 @@
     r = iesys_check_sequence_async(esysContext);
     if (r != TSS2_RC_SUCCESS)
         return r;
-    r = check_session_feasability(shandle1, shandle2, shandle3, 1);
-    return_if_error(r, "Check session usage");
+    esysContext->state = _ESYS_STATE_INTERNALERROR;
 
+    /* Check and store input parameters */
+    r = check_session_feasability(shandle1, shandle2, shandle3, 1);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Check session usage");
     store_input_parameters(esysContext, auth,
                 auditAlg,
                 setList,
                 clearList);
+
+    /* Retrieve the metadata objects for provided handles */
     r = esys_GetResourceObject(esysContext, auth, &authNode);
-    if (r != TPM2_RC_SUCCESS)
-        return r;
+    return_state_if_error(r, _ESYS_STATE_INIT, "auth unknown.");
+
+    /* Initial invocation of SAPI to prepare the command buffer with parameters */
     r = Tss2_Sys_SetCommandCodeAuditStatus_Prepare(esysContext->sys,
                 (authNode == NULL) ? TPM2_RH_NULL : authNode->rsrc.handle,
                 auditAlg,
                 setList,
                 clearList);
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error async SetCommandCodeAuditStatus");
-        return r;
-    }
-    r = init_session_tab(esysContext, shandle1, shandle2, shandle3);
-    return_if_error(r, "Initialize session resources");
+    return_state_if_error(r, _ESYS_STATE_INIT, "SAPI Prepare returned error.");
 
+    /* Calculate the cpHash Values */
+    r = init_session_tab(esysContext, shandle1, shandle2, shandle3);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Initialize session resources");
     iesys_compute_session_value(esysContext->session_tab[0],
                 &authNode->rsrc.name, &authNode->auth);
     iesys_compute_session_value(esysContext->session_tab[1], NULL, NULL);
     iesys_compute_session_value(esysContext->session_tab[2], NULL, NULL);
-    r = iesys_gen_auths(esysContext, authNode, NULL, NULL, &auths);
-    return_if_error(r, "Error in computation of auth values");
 
+    /* Generate the auth values and set them in the SAPI command buffer */
+    r = iesys_gen_auths(esysContext, authNode, NULL, NULL, &auths);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Error in computation of auth values");
     esysContext->authsCount = auths.count;
     r = Tss2_Sys_SetCmdAuths(esysContext->sys, &auths);
-    if (r != TSS2_RC_SUCCESS) {
-        return r;
-    }
+    return_state_if_error(r, _ESYS_STATE_INIT, "SAPI error on SetCmdAuths");
 
+    /* Trigger execution and finish the async invocation */
     r = Tss2_Sys_ExecuteAsync(esysContext->sys);
-    return_if_error(r, "Finish (Execute Async)");
+    return_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Finish (Execute Async)");
 
     esysContext->state = _ESYS_STATE_SENT;
 
@@ -235,26 +239,34 @@
     ESYS_CONTEXT *esysContext)
 {
     LOG_TRACE("complete");
+    TSS2_RC r;
     if (esysContext == NULL) {
         LOG_ERROR("esyscontext is NULL.");
         return TSS2_ESYS_RC_BAD_REFERENCE;
     }
+
+    /* Check for correct sequence and set sequence to irregular for now */
     if (esysContext->state != _ESYS_STATE_SENT) {
         LOG_ERROR("Esys called in bad sequence.");
         return TSS2_ESYS_RC_BAD_SEQUENCE;
     }
-    TSS2_RC r;
+    esysContext->state = _ESYS_STATE_INTERNALERROR;
+
+    /*Receive the TPM response and handle resubmissions if necessary. */
     r = Tss2_Sys_ExecuteFinish(esysContext->sys, esysContext->timeout);
     if ((r & ~TSS2_RC_LAYER_MASK) == TSS2_BASE_RC_TRY_AGAIN) {
         LOG_DEBUG("A layer below returned TRY_AGAIN: %" PRIx32, r);
+        esysContext->state = _ESYS_STATE_SENT;
         return r;
     }
+    /* This block handle the resubmission of TPM commands given a certain set of
+     * TPM response codes. */
     if (r == TPM2_RC_RETRY || r == TPM2_RC_TESTING || r == TPM2_RC_YIELDED) {
         LOG_DEBUG("TPM returned RETRY, TESTING or YIELDED, which triggers a "
             "resubmission: %" PRIx32, r);
         if (esysContext->submissionCount >= _ESYS_MAX_SUBMISSIONS) {
-            LOG_WARNING("Maximum number of resubmissions has been reached.");
-            esysContext->state = _ESYS_STATE_ERRORRESPONSE;
+            LOG_WARNING("Maximum number of (re)submissions has been reached.");
+            esysContext->state = _ESYS_STATE_INIT;
             return r;
         }
         esysContext->state = _ESYS_STATE_RESUBMISSION;
@@ -267,33 +279,42 @@
                 esysContext->in.SetCommandCodeAuditStatus.setList,
                 esysContext->in.SetCommandCodeAuditStatus.clearList);
         if (r != TSS2_RC_SUCCESS) {
-            LOG_ERROR("Error attempting to resubmit");
+            LOG_WARNING("Error attempting to resubmit");
+            /* We do not set esysContext->state here but inherit the most recent
+             * state of the _async function. */
             return r;
         }
         r = TSS2_ESYS_RC_TRY_AGAIN;
+        LOG_DEBUG("Resubmission initiated and returning RC_TRY_AGAIN.");
         return r;
     }
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error finish (ExecuteFinish) SetCommandCodeAuditStatus");
+    /* The following is the "regular error" handling. */
+    if (r != TSS2_RC_SUCCESS && (r & TSS2_RC_LAYER_MASK) == 0) {
+        LOG_WARNING("Received TPM Error");
+        esysContext->state = _ESYS_STATE_INIT;
+        return r;
+    } else if (r != TSS2_RC_SUCCESS) {
+        LOG_ERROR("Received a non-TPM Error");
+        esysContext->state = _ESYS_STATE_INTERNALERROR;
         return r;
     }
+
     /*
      * Now the verification of the response (hmac check) and if necessary the
-     * parameter decryption have to be done
+     * parameter decryption have to be done.
      */
     r = iesys_check_response(esysContext);
-    return_if_error(r, "Error: check response");
+    return_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Error: check response");
     /*
      * After the verification of the response we call the complete function
      * to deliver the result.
      */
     r = Tss2_Sys_SetCommandCodeAuditStatus_Complete(esysContext->sys);
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error finish (ExecuteFinish) SetCommandCodeAuditStatus: %" PRIx32, r);
-        esysContext->state = _ESYS_STATE_ERRORRESPONSE;
-        return r;;
-    }
-    esysContext->state = _ESYS_STATE_FINISHED;
+    return_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Received error from SAPI"
+                        " unmarshalling" );
+    esysContext->state = _ESYS_STATE_INIT;
+    LOG_DEBUG("context=%p",
+              esysContext);
 
-    return r;
+    return TSS2_RC_SUCCESS;
 }
diff --git a/src/tss2-esys/api/Esys_SetPrimaryPolicy.c b/src/tss2-esys/api/Esys_SetPrimaryPolicy.c
index 0c3d691..65eaee4 100644
--- a/src/tss2-esys/api/Esys_SetPrimaryPolicy.c
+++ b/src/tss2-esys/api/Esys_SetPrimaryPolicy.c
@@ -155,6 +155,7 @@
     TSS2L_SYS_AUTH_COMMAND auths;
     RSRC_NODE_T *authHandleNode;
 
+    /* Check context, sequence correctness and set state to error for now */
     if (esysContext == NULL) {
         LOG_ERROR("esyscontext is NULL.");
         return TSS2_ESYS_RC_BAD_REFERENCE;
@@ -162,41 +163,44 @@
     r = iesys_check_sequence_async(esysContext);
     if (r != TSS2_RC_SUCCESS)
         return r;
-    r = check_session_feasability(shandle1, shandle2, shandle3, 1);
-    return_if_error(r, "Check session usage");
+    esysContext->state = _ESYS_STATE_INTERNALERROR;
 
+    /* Check and store input parameters */
+    r = check_session_feasability(shandle1, shandle2, shandle3, 1);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Check session usage");
     store_input_parameters(esysContext, authHandle,
                 authPolicy,
                 hashAlg);
+
+    /* Retrieve the metadata objects for provided handles */
     r = esys_GetResourceObject(esysContext, authHandle, &authHandleNode);
-    if (r != TPM2_RC_SUCCESS)
-        return r;
+    return_state_if_error(r, _ESYS_STATE_INIT, "authHandle unknown.");
+
+    /* Initial invocation of SAPI to prepare the command buffer with parameters */
     r = Tss2_Sys_SetPrimaryPolicy_Prepare(esysContext->sys,
                 (authHandleNode == NULL) ? TPM2_RH_NULL : authHandleNode->rsrc.handle,
                 authPolicy,
                 hashAlg);
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error async SetPrimaryPolicy");
-        return r;
-    }
-    r = init_session_tab(esysContext, shandle1, shandle2, shandle3);
-    return_if_error(r, "Initialize session resources");
+    return_state_if_error(r, _ESYS_STATE_INIT, "SAPI Prepare returned error.");
 
+    /* Calculate the cpHash Values */
+    r = init_session_tab(esysContext, shandle1, shandle2, shandle3);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Initialize session resources");
     iesys_compute_session_value(esysContext->session_tab[0],
                 &authHandleNode->rsrc.name, &authHandleNode->auth);
     iesys_compute_session_value(esysContext->session_tab[1], NULL, NULL);
     iesys_compute_session_value(esysContext->session_tab[2], NULL, NULL);
-    r = iesys_gen_auths(esysContext, authHandleNode, NULL, NULL, &auths);
-    return_if_error(r, "Error in computation of auth values");
 
+    /* Generate the auth values and set them in the SAPI command buffer */
+    r = iesys_gen_auths(esysContext, authHandleNode, NULL, NULL, &auths);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Error in computation of auth values");
     esysContext->authsCount = auths.count;
     r = Tss2_Sys_SetCmdAuths(esysContext->sys, &auths);
-    if (r != TSS2_RC_SUCCESS) {
-        return r;
-    }
+    return_state_if_error(r, _ESYS_STATE_INIT, "SAPI error on SetCmdAuths");
 
+    /* Trigger execution and finish the async invocation */
     r = Tss2_Sys_ExecuteAsync(esysContext->sys);
-    return_if_error(r, "Finish (Execute Async)");
+    return_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Finish (Execute Async)");
 
     esysContext->state = _ESYS_STATE_SENT;
 
@@ -220,26 +224,34 @@
     ESYS_CONTEXT *esysContext)
 {
     LOG_TRACE("complete");
+    TSS2_RC r;
     if (esysContext == NULL) {
         LOG_ERROR("esyscontext is NULL.");
         return TSS2_ESYS_RC_BAD_REFERENCE;
     }
+
+    /* Check for correct sequence and set sequence to irregular for now */
     if (esysContext->state != _ESYS_STATE_SENT) {
         LOG_ERROR("Esys called in bad sequence.");
         return TSS2_ESYS_RC_BAD_SEQUENCE;
     }
-    TSS2_RC r;
+    esysContext->state = _ESYS_STATE_INTERNALERROR;
+
+    /*Receive the TPM response and handle resubmissions if necessary. */
     r = Tss2_Sys_ExecuteFinish(esysContext->sys, esysContext->timeout);
     if ((r & ~TSS2_RC_LAYER_MASK) == TSS2_BASE_RC_TRY_AGAIN) {
         LOG_DEBUG("A layer below returned TRY_AGAIN: %" PRIx32, r);
+        esysContext->state = _ESYS_STATE_SENT;
         return r;
     }
+    /* This block handle the resubmission of TPM commands given a certain set of
+     * TPM response codes. */
     if (r == TPM2_RC_RETRY || r == TPM2_RC_TESTING || r == TPM2_RC_YIELDED) {
         LOG_DEBUG("TPM returned RETRY, TESTING or YIELDED, which triggers a "
             "resubmission: %" PRIx32, r);
         if (esysContext->submissionCount >= _ESYS_MAX_SUBMISSIONS) {
-            LOG_WARNING("Maximum number of resubmissions has been reached.");
-            esysContext->state = _ESYS_STATE_ERRORRESPONSE;
+            LOG_WARNING("Maximum number of (re)submissions has been reached.");
+            esysContext->state = _ESYS_STATE_INIT;
             return r;
         }
         esysContext->state = _ESYS_STATE_RESUBMISSION;
@@ -251,33 +263,42 @@
                 esysContext->in.SetPrimaryPolicy.authPolicy,
                 esysContext->in.SetPrimaryPolicy.hashAlg);
         if (r != TSS2_RC_SUCCESS) {
-            LOG_ERROR("Error attempting to resubmit");
+            LOG_WARNING("Error attempting to resubmit");
+            /* We do not set esysContext->state here but inherit the most recent
+             * state of the _async function. */
             return r;
         }
         r = TSS2_ESYS_RC_TRY_AGAIN;
+        LOG_DEBUG("Resubmission initiated and returning RC_TRY_AGAIN.");
         return r;
     }
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error finish (ExecuteFinish) SetPrimaryPolicy");
+    /* The following is the "regular error" handling. */
+    if (r != TSS2_RC_SUCCESS && (r & TSS2_RC_LAYER_MASK) == 0) {
+        LOG_WARNING("Received TPM Error");
+        esysContext->state = _ESYS_STATE_INIT;
+        return r;
+    } else if (r != TSS2_RC_SUCCESS) {
+        LOG_ERROR("Received a non-TPM Error");
+        esysContext->state = _ESYS_STATE_INTERNALERROR;
         return r;
     }
+
     /*
      * Now the verification of the response (hmac check) and if necessary the
-     * parameter decryption have to be done
+     * parameter decryption have to be done.
      */
     r = iesys_check_response(esysContext);
-    return_if_error(r, "Error: check response");
+    return_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Error: check response");
     /*
      * After the verification of the response we call the complete function
      * to deliver the result.
      */
     r = Tss2_Sys_SetPrimaryPolicy_Complete(esysContext->sys);
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error finish (ExecuteFinish) SetPrimaryPolicy: %" PRIx32, r);
-        esysContext->state = _ESYS_STATE_ERRORRESPONSE;
-        return r;;
-    }
-    esysContext->state = _ESYS_STATE_FINISHED;
+    return_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Received error from SAPI"
+                        " unmarshalling" );
+    esysContext->state = _ESYS_STATE_INIT;
+    LOG_DEBUG("context=%p",
+              esysContext);
 
-    return r;
+    return TSS2_RC_SUCCESS;
 }
diff --git a/src/tss2-esys/api/Esys_Shutdown.c b/src/tss2-esys/api/Esys_Shutdown.c
index fafd4fd..b055db4 100644
--- a/src/tss2-esys/api/Esys_Shutdown.c
+++ b/src/tss2-esys/api/Esys_Shutdown.c
@@ -132,6 +132,7 @@
     TSS2_RC r;
     TSS2L_SYS_AUTH_COMMAND auths;
 
+    /* Check context, sequence correctness and set state to error for now */
     if (esysContext == NULL) {
         LOG_ERROR("esyscontext is NULL.");
         return TSS2_ESYS_RC_BAD_REFERENCE;
@@ -139,32 +140,36 @@
     r = iesys_check_sequence_async(esysContext);
     if (r != TSS2_RC_SUCCESS)
         return r;
-    r = check_session_feasability(shandle1, shandle2, shandle3, 0);
-    return_if_error(r, "Check session usage");
+    esysContext->state = _ESYS_STATE_INTERNALERROR;
 
+    /* Check and store input parameters */
+    r = check_session_feasability(shandle1, shandle2, shandle3, 0);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Check session usage");
     store_input_parameters(esysContext,
                 shutdownType);
+
+    /* Initial invocation of SAPI to prepare the command buffer with parameters */
     r = Tss2_Sys_Shutdown_Prepare(esysContext->sys,
                 shutdownType);
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error async Shutdown");
-        return r;
-    }
+    return_state_if_error(r, _ESYS_STATE_INIT, "SAPI Prepare returned error.");
+
+    /* Calculate the cpHash Values */
     r = init_session_tab(esysContext, shandle1, shandle2, shandle3);
-    return_if_error(r, "Initialize session resources");
-
+    return_state_if_error(r, _ESYS_STATE_INIT, "Initialize session resources");
     iesys_compute_session_value(esysContext->session_tab[0], NULL, NULL);
-    r = iesys_gen_auths(esysContext, NULL, NULL, NULL, &auths);
-    return_if_error(r, "Error in computation of auth values");
+    iesys_compute_session_value(esysContext->session_tab[1], NULL, NULL);
+    iesys_compute_session_value(esysContext->session_tab[2], NULL, NULL);
 
+    /* Generate the auth values and set them in the SAPI command buffer */
+    r = iesys_gen_auths(esysContext, NULL, NULL, NULL, &auths);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Error in computation of auth values");
     esysContext->authsCount = auths.count;
     r = Tss2_Sys_SetCmdAuths(esysContext->sys, &auths);
-    if (r != TSS2_RC_SUCCESS) {
-        return r;
-    }
+    return_state_if_error(r, _ESYS_STATE_INIT, "SAPI error on SetCmdAuths");
 
+    /* Trigger execution and finish the async invocation */
     r = Tss2_Sys_ExecuteAsync(esysContext->sys);
-    return_if_error(r, "Finish (Execute Async)");
+    return_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Finish (Execute Async)");
 
     esysContext->state = _ESYS_STATE_SENT;
 
@@ -188,26 +193,34 @@
     ESYS_CONTEXT *esysContext)
 {
     LOG_TRACE("complete");
+    TSS2_RC r;
     if (esysContext == NULL) {
         LOG_ERROR("esyscontext is NULL.");
         return TSS2_ESYS_RC_BAD_REFERENCE;
     }
+
+    /* Check for correct sequence and set sequence to irregular for now */
     if (esysContext->state != _ESYS_STATE_SENT) {
         LOG_ERROR("Esys called in bad sequence.");
         return TSS2_ESYS_RC_BAD_SEQUENCE;
     }
-    TSS2_RC r;
+    esysContext->state = _ESYS_STATE_INTERNALERROR;
+
+    /*Receive the TPM response and handle resubmissions if necessary. */
     r = Tss2_Sys_ExecuteFinish(esysContext->sys, esysContext->timeout);
     if ((r & ~TSS2_RC_LAYER_MASK) == TSS2_BASE_RC_TRY_AGAIN) {
         LOG_DEBUG("A layer below returned TRY_AGAIN: %" PRIx32, r);
+        esysContext->state = _ESYS_STATE_SENT;
         return r;
     }
+    /* This block handle the resubmission of TPM commands given a certain set of
+     * TPM response codes. */
     if (r == TPM2_RC_RETRY || r == TPM2_RC_TESTING || r == TPM2_RC_YIELDED) {
         LOG_DEBUG("TPM returned RETRY, TESTING or YIELDED, which triggers a "
             "resubmission: %" PRIx32, r);
         if (esysContext->submissionCount >= _ESYS_MAX_SUBMISSIONS) {
-            LOG_WARNING("Maximum number of resubmissions has been reached.");
-            esysContext->state = _ESYS_STATE_ERRORRESPONSE;
+            LOG_WARNING("Maximum number of (re)submissions has been reached.");
+            esysContext->state = _ESYS_STATE_INIT;
             return r;
         }
         esysContext->state = _ESYS_STATE_RESUBMISSION;
@@ -217,33 +230,42 @@
                 esysContext->session_type[2],
                 esysContext->in.Shutdown.shutdownType);
         if (r != TSS2_RC_SUCCESS) {
-            LOG_ERROR("Error attempting to resubmit");
+            LOG_WARNING("Error attempting to resubmit");
+            /* We do not set esysContext->state here but inherit the most recent
+             * state of the _async function. */
             return r;
         }
         r = TSS2_ESYS_RC_TRY_AGAIN;
+        LOG_DEBUG("Resubmission initiated and returning RC_TRY_AGAIN.");
         return r;
     }
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error finish (ExecuteFinish) Shutdown");
+    /* The following is the "regular error" handling. */
+    if (r != TSS2_RC_SUCCESS && (r & TSS2_RC_LAYER_MASK) == 0) {
+        LOG_WARNING("Received TPM Error");
+        esysContext->state = _ESYS_STATE_INIT;
+        return r;
+    } else if (r != TSS2_RC_SUCCESS) {
+        LOG_ERROR("Received a non-TPM Error");
+        esysContext->state = _ESYS_STATE_INTERNALERROR;
         return r;
     }
+
     /*
      * Now the verification of the response (hmac check) and if necessary the
-     * parameter decryption have to be done
+     * parameter decryption have to be done.
      */
     r = iesys_check_response(esysContext);
-    return_if_error(r, "Error: check response");
+    return_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Error: check response");
     /*
      * After the verification of the response we call the complete function
      * to deliver the result.
      */
     r = Tss2_Sys_Shutdown_Complete(esysContext->sys);
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error finish (ExecuteFinish) Shutdown: %" PRIx32, r);
-        esysContext->state = _ESYS_STATE_ERRORRESPONSE;
-        return r;;
-    }
-    esysContext->state = _ESYS_STATE_FINISHED;
+    return_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Received error from SAPI"
+                        " unmarshalling" );
+    esysContext->state = _ESYS_STATE_INIT;
+    LOG_DEBUG("context=%p",
+              esysContext);
 
-    return r;
+    return TSS2_RC_SUCCESS;
 }
diff --git a/src/tss2-esys/api/Esys_Sign.c b/src/tss2-esys/api/Esys_Sign.c
index 7feb278..d8edd9b 100644
--- a/src/tss2-esys/api/Esys_Sign.c
+++ b/src/tss2-esys/api/Esys_Sign.c
@@ -178,6 +178,7 @@
     TSS2L_SYS_AUTH_COMMAND auths;
     RSRC_NODE_T *keyHandleNode;
 
+    /* Check context, sequence correctness and set state to error for now */
     if (esysContext == NULL) {
         LOG_ERROR("esyscontext is NULL.");
         return TSS2_ESYS_RC_BAD_REFERENCE;
@@ -185,43 +186,46 @@
     r = iesys_check_sequence_async(esysContext);
     if (r != TSS2_RC_SUCCESS)
         return r;
-    r = check_session_feasability(shandle1, shandle2, shandle3, 1);
-    return_if_error(r, "Check session usage");
+    esysContext->state = _ESYS_STATE_INTERNALERROR;
 
+    /* Check and store input parameters */
+    r = check_session_feasability(shandle1, shandle2, shandle3, 1);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Check session usage");
     store_input_parameters(esysContext, keyHandle,
                 digest,
                 inScheme,
                 validation);
+
+    /* Retrieve the metadata objects for provided handles */
     r = esys_GetResourceObject(esysContext, keyHandle, &keyHandleNode);
-    if (r != TPM2_RC_SUCCESS)
-        return r;
+    return_state_if_error(r, _ESYS_STATE_INIT, "keyHandle unknown.");
+
+    /* Initial invocation of SAPI to prepare the command buffer with parameters */
     r = Tss2_Sys_Sign_Prepare(esysContext->sys,
                 (keyHandleNode == NULL) ? TPM2_RH_NULL : keyHandleNode->rsrc.handle,
                 digest,
                 inScheme,
                 validation);
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error async Sign");
-        return r;
-    }
-    r = init_session_tab(esysContext, shandle1, shandle2, shandle3);
-    return_if_error(r, "Initialize session resources");
+    return_state_if_error(r, _ESYS_STATE_INIT, "SAPI Prepare returned error.");
 
+    /* Calculate the cpHash Values */
+    r = init_session_tab(esysContext, shandle1, shandle2, shandle3);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Initialize session resources");
     iesys_compute_session_value(esysContext->session_tab[0],
                 &keyHandleNode->rsrc.name, &keyHandleNode->auth);
     iesys_compute_session_value(esysContext->session_tab[1], NULL, NULL);
     iesys_compute_session_value(esysContext->session_tab[2], NULL, NULL);
-    r = iesys_gen_auths(esysContext, keyHandleNode, NULL, NULL, &auths);
-    return_if_error(r, "Error in computation of auth values");
 
+    /* Generate the auth values and set them in the SAPI command buffer */
+    r = iesys_gen_auths(esysContext, keyHandleNode, NULL, NULL, &auths);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Error in computation of auth values");
     esysContext->authsCount = auths.count;
     r = Tss2_Sys_SetCmdAuths(esysContext->sys, &auths);
-    if (r != TSS2_RC_SUCCESS) {
-        return r;
-    }
+    return_state_if_error(r, _ESYS_STATE_INIT, "SAPI error on SetCmdAuths");
 
+    /* Trigger execution and finish the async invocation */
     r = Tss2_Sys_ExecuteAsync(esysContext->sys);
-    return_if_error(r, "Finish (Execute Async)");
+    return_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Finish (Execute Async)");
 
     esysContext->state = _ESYS_STATE_SENT;
 
@@ -248,32 +252,42 @@
     TPMT_SIGNATURE **signature)
 {
     LOG_TRACE("complete");
+    TSS2_RC r;
     if (esysContext == NULL) {
         LOG_ERROR("esyscontext is NULL.");
         return TSS2_ESYS_RC_BAD_REFERENCE;
     }
+
+    /* Check for correct sequence and set sequence to irregular for now */
     if (esysContext->state != _ESYS_STATE_SENT) {
         LOG_ERROR("Esys called in bad sequence.");
         return TSS2_ESYS_RC_BAD_SEQUENCE;
     }
-    TSS2_RC r;
+    esysContext->state = _ESYS_STATE_INTERNALERROR;
+
+    /* Allocate memory for response parameters */
     if (signature != NULL) {
         *signature = calloc(sizeof(TPMT_SIGNATURE), 1);
         if (*signature == NULL) {
             return_error(TSS2_ESYS_RC_MEMORY, "Out of memory");
         }
     }
+
+    /*Receive the TPM response and handle resubmissions if necessary. */
     r = Tss2_Sys_ExecuteFinish(esysContext->sys, esysContext->timeout);
     if ((r & ~TSS2_RC_LAYER_MASK) == TSS2_BASE_RC_TRY_AGAIN) {
         LOG_DEBUG("A layer below returned TRY_AGAIN: %" PRIx32, r);
+        esysContext->state = _ESYS_STATE_SENT;
         goto error_cleanup;
     }
+    /* This block handle the resubmission of TPM commands given a certain set of
+     * TPM response codes. */
     if (r == TPM2_RC_RETRY || r == TPM2_RC_TESTING || r == TPM2_RC_YIELDED) {
         LOG_DEBUG("TPM returned RETRY, TESTING or YIELDED, which triggers a "
             "resubmission: %" PRIx32, r);
         if (esysContext->submissionCount >= _ESYS_MAX_SUBMISSIONS) {
-            LOG_WARNING("Maximum number of resubmissions has been reached.");
-            esysContext->state = _ESYS_STATE_ERRORRESPONSE;
+            LOG_WARNING("Maximum number of (re)submissions has been reached.");
+            esysContext->state = _ESYS_STATE_INIT;
             goto error_cleanup;
         }
         esysContext->state = _ESYS_STATE_RESUBMISSION;
@@ -286,22 +300,32 @@
                 esysContext->in.Sign.inScheme,
                 esysContext->in.Sign.validation);
         if (r != TSS2_RC_SUCCESS) {
-            LOG_ERROR("Error attempting to resubmit");
+            LOG_WARNING("Error attempting to resubmit");
+            /* We do not set esysContext->state here but inherit the most recent
+             * state of the _async function. */
             goto error_cleanup;
         }
         r = TSS2_ESYS_RC_TRY_AGAIN;
+        LOG_DEBUG("Resubmission initiated and returning RC_TRY_AGAIN.");
         goto error_cleanup;
     }
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error finish (ExecuteFinish) Sign");
+    /* The following is the "regular error" handling. */
+    if (r != TSS2_RC_SUCCESS && (r & TSS2_RC_LAYER_MASK) == 0) {
+        LOG_WARNING("Received TPM Error");
+        esysContext->state = _ESYS_STATE_INIT;
+        goto error_cleanup;
+    } else if (r != TSS2_RC_SUCCESS) {
+        LOG_ERROR("Received a non-TPM Error");
+        esysContext->state = _ESYS_STATE_INTERNALERROR;
         goto error_cleanup;
     }
+
     /*
      * Now the verification of the response (hmac check) and if necessary the
-     * parameter decryption have to be done
+     * parameter decryption have to be done.
      */
     r = iesys_check_response(esysContext);
-    goto_if_error(r, "Error: check response",
+    goto_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Error: check response",
                       error_cleanup);
     /*
      * After the verification of the response we call the complete function
@@ -309,17 +333,17 @@
      */
     r = Tss2_Sys_Sign_Complete(esysContext->sys,
                 (signature != NULL) ? *signature : NULL);
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error finish (ExecuteFinish) Sign: %" PRIx32, r);
-        esysContext->state = _ESYS_STATE_ERRORRESPONSE;
-        goto error_cleanup;;
-    }
-    esysContext->state = _ESYS_STATE_FINISHED;
+    goto_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Received error from SAPI"
+                        " unmarshalling" ,error_cleanup);
+    esysContext->state = _ESYS_STATE_INIT;
+    LOG_DEBUG("context=%p, signature=%p",
+              esysContext, signature);
 
-    return r;
+    return TSS2_RC_SUCCESS;
 
 error_cleanup:
     if (signature != NULL)
         SAFE_FREE(*signature);
+
     return r;
 }
diff --git a/src/tss2-esys/api/Esys_StartAuthSession.c b/src/tss2-esys/api/Esys_StartAuthSession.c
index 5beae64..35a4f76 100644
--- a/src/tss2-esys/api/Esys_StartAuthSession.c
+++ b/src/tss2-esys/api/Esys_StartAuthSession.c
@@ -196,6 +196,7 @@
     RSRC_NODE_T *tpmKeyNode;
     RSRC_NODE_T *bindNode;
 
+    /* Check context, sequence correctness and set state to error for now */
     if (esysContext == NULL) {
         LOG_ERROR("esyscontext is NULL.");
         return TSS2_ESYS_RC_BAD_REFERENCE;
@@ -203,21 +204,22 @@
     r = iesys_check_sequence_async(esysContext);
     if (r != TSS2_RC_SUCCESS)
         return r;
-    r = check_session_feasability(shandle1, shandle2, shandle3, 0);
-    return_if_error(r, "Check session usage");
+    esysContext->state = _ESYS_STATE_INTERNALERROR;
 
+    /* Check and store input parameters */
+    r = check_session_feasability(shandle1, shandle2, shandle3, 0);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Check session usage");
     store_input_parameters(esysContext, tpmKey, bind,
                 nonceCaller,
                 sessionType,
                 symmetric,
                 authHash);
+
+    /* Retrieve the metadata objects for provided handles */
     r = esys_GetResourceObject(esysContext, tpmKey, &tpmKeyNode);
-    if (r != TPM2_RC_SUCCESS)
-        return r;
+    return_state_if_error(r, _ESYS_STATE_INIT, "tpmKey unknown.");
     r = esys_GetResourceObject(esysContext, bind, &bindNode);
-    if (r != TPM2_RC_SUCCESS)
-        return r;
-    size_t keyHash_size = 0;
+    return_state_if_error(r, _ESYS_STATE_INIT, "bind unknown.");
     size_t authHash_size = 0;
     TSS2_RC r2;
     r2 = iesys_compute_encrypted_salt(esysContext, tpmKeyNode,
@@ -242,6 +244,8 @@
         nonceCaller = esysContext->in.StartAuthSession.nonceCaller;
     }
 
+
+    /* Initial invocation of SAPI to prepare the command buffer with parameters */
     r = Tss2_Sys_StartAuthSession_Prepare(esysContext->sys,
                 (tpmKeyNode == NULL) ? TPM2_RH_NULL : tpmKeyNode->rsrc.handle,
                 (bindNode == NULL) ? TPM2_RH_NULL : bindNode->rsrc.handle,
@@ -250,27 +254,25 @@
                 sessionType,
                 symmetric,
                 authHash);
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error async StartAuthSession");
-        return r;
-    }
-    r = init_session_tab(esysContext, shandle1, shandle2, shandle3);
-    return_if_error(r, "Initialize session resources");
+    return_state_if_error(r, _ESYS_STATE_INIT, "SAPI Prepare returned error.");
 
+    /* Calculate the cpHash Values */
+    r = init_session_tab(esysContext, shandle1, shandle2, shandle3);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Initialize session resources");
     iesys_compute_session_value(esysContext->session_tab[0], NULL, NULL);
     iesys_compute_session_value(esysContext->session_tab[1], NULL, NULL);
     iesys_compute_session_value(esysContext->session_tab[2], NULL, NULL);
-    r = iesys_gen_auths(esysContext, tpmKeyNode, bindNode, NULL, &auths);
-    return_if_error(r, "Error in computation of auth values");
 
+    /* Generate the auth values and set them in the SAPI command buffer */
+    r = iesys_gen_auths(esysContext, tpmKeyNode, bindNode, NULL, &auths);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Error in computation of auth values");
     esysContext->authsCount = auths.count;
     r = Tss2_Sys_SetCmdAuths(esysContext->sys, &auths);
-    if (r != TSS2_RC_SUCCESS) {
-        return r;
-    }
+    return_state_if_error(r, _ESYS_STATE_INIT, "SAPI error on SetCmdAuths");
 
+    /* Trigger execution and finish the async invocation */
     r = Tss2_Sys_ExecuteAsync(esysContext->sys);
-    return_if_error(r, "Finish (Execute Async)");
+    return_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Finish (Execute Async)");
 
     esysContext->state = _ESYS_STATE_SENT;
 
@@ -300,18 +302,22 @@
 {
     TPM2B_NONCE *lnonceTPM = NULL;
     LOG_TRACE("complete");
+    TSS2_RC r;
     if (esysContext == NULL) {
         LOG_ERROR("esyscontext is NULL.");
         return TSS2_ESYS_RC_BAD_REFERENCE;
     }
+
+    /* Check for correct sequence and set sequence to irregular for now */
     if (esysContext->state != _ESYS_STATE_SENT) {
         LOG_ERROR("Esys called in bad sequence.");
         return TSS2_ESYS_RC_BAD_SEQUENCE;
     }
-    TSS2_RC r;
-    IESYS_RESOURCE *sessionHandleRsrc = NULL;
+    esysContext->state = _ESYS_STATE_INTERNALERROR;
     RSRC_NODE_T *sessionHandleNode = NULL;
 
+
+    /* Allocate memory for response parameters */
     if (sessionHandle == NULL) {
         LOG_ERROR("Handle sessionHandle may not be NULL");
         return TSS2_ESYS_RC_BAD_REFERENCE;
@@ -336,17 +342,22 @@
         *esysContext->in.StartAuthSession.symmetric;
     rsrc->misc.rsrc_session.nonceCaller =
         esysContext->in.StartAuthSession.nonceCallerData;
+
+    /*Receive the TPM response and handle resubmissions if necessary. */
     r = Tss2_Sys_ExecuteFinish(esysContext->sys, esysContext->timeout);
     if ((r & ~TSS2_RC_LAYER_MASK) == TSS2_BASE_RC_TRY_AGAIN) {
         LOG_DEBUG("A layer below returned TRY_AGAIN: %" PRIx32, r);
+        esysContext->state = _ESYS_STATE_SENT;
         goto error_cleanup;
     }
+    /* This block handle the resubmission of TPM commands given a certain set of
+     * TPM response codes. */
     if (r == TPM2_RC_RETRY || r == TPM2_RC_TESTING || r == TPM2_RC_YIELDED) {
         LOG_DEBUG("TPM returned RETRY, TESTING or YIELDED, which triggers a "
             "resubmission: %" PRIx32, r);
         if (esysContext->submissionCount >= _ESYS_MAX_SUBMISSIONS) {
-            LOG_WARNING("Maximum number of resubmissions has been reached.");
-            esysContext->state = _ESYS_STATE_ERRORRESPONSE;
+            LOG_WARNING("Maximum number of (re)submissions has been reached.");
+            esysContext->state = _ESYS_STATE_INIT;
             goto error_cleanup;
         }
         esysContext->state = _ESYS_STATE_RESUBMISSION;
@@ -361,22 +372,32 @@
                 esysContext->in.StartAuthSession.symmetric,
                 esysContext->in.StartAuthSession.authHash);
         if (r != TSS2_RC_SUCCESS) {
-            LOG_ERROR("Error attempting to resubmit");
+            LOG_WARNING("Error attempting to resubmit");
+            /* We do not set esysContext->state here but inherit the most recent
+             * state of the _async function. */
             goto error_cleanup;
         }
         r = TSS2_ESYS_RC_TRY_AGAIN;
+        LOG_DEBUG("Resubmission initiated and returning RC_TRY_AGAIN.");
         goto error_cleanup;
     }
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error finish (ExecuteFinish) StartAuthSession");
+    /* The following is the "regular error" handling. */
+    if (r != TSS2_RC_SUCCESS && (r & TSS2_RC_LAYER_MASK) == 0) {
+        LOG_WARNING("Received TPM Error");
+        esysContext->state = _ESYS_STATE_INIT;
+        goto error_cleanup;
+    } else if (r != TSS2_RC_SUCCESS) {
+        LOG_ERROR("Received a non-TPM Error");
+        esysContext->state = _ESYS_STATE_INTERNALERROR;
         goto error_cleanup;
     }
+
     /*
      * Now the verification of the response (hmac check) and if necessary the
-     * parameter decryption have to be done
+     * parameter decryption have to be done.
      */
     r = iesys_check_response(esysContext);
-    goto_if_error(r, "Error: check response",
+    goto_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Error: check response",
                       error_cleanup);
     /*
      * After the verification of the response we call the complete function
@@ -385,11 +406,8 @@
     r = Tss2_Sys_StartAuthSession_Complete(esysContext->sys,
                 &sessionHandleNode->rsrc.handle,
                 lnonceTPM);
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error finish (ExecuteFinish) StartAuthSession: %" PRIx32, r);
-        esysContext->state = _ESYS_STATE_ERRORRESPONSE;
-        goto error_cleanup;;
-    }
+    goto_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Received error from SAPI"
+                        " unmarshalling" ,error_cleanup);
 
     sessionHandleNode->rsrc.misc.rsrc_session.nonceTPM = *lnonceTPM;
     sessionHandleNode->rsrc.rsrcType = IESYSC_SESSION_RSRC;
@@ -470,12 +488,15 @@
     else
         SAFE_FREE(lnonceTPM);
 
-    esysContext->state = _ESYS_STATE_FINISHED;
+    esysContext->state = _ESYS_STATE_INIT;
+    LOG_DEBUG("context=%p, sessionHandle=%p, nonceTPM=%p",
+              esysContext, sessionHandle, nonceTPM);
 
-    return r;
+    return TSS2_RC_SUCCESS;
 
 error_cleanup:
     Esys_TR_Close(esysContext, sessionHandle);
     SAFE_FREE(lnonceTPM);
+
     return r;
 }
diff --git a/src/tss2-esys/api/Esys_Startup.c b/src/tss2-esys/api/Esys_Startup.c
index 483a300..18b10ac 100644
--- a/src/tss2-esys/api/Esys_Startup.c
+++ b/src/tss2-esys/api/Esys_Startup.c
@@ -116,6 +116,7 @@
 {
     TSS2_RC r;
 
+    /* Check context, sequence correctness and set state to error for now */
     if (esysContext == NULL) {
         LOG_ERROR("esyscontext is NULL.");
         return TSS2_ESYS_RC_BAD_REFERENCE;
@@ -123,17 +124,17 @@
     r = iesys_check_sequence_async(esysContext);
     if (r != TSS2_RC_SUCCESS)
         return r;
-
+    esysContext->state = _ESYS_STATE_INTERNALERROR;
     store_input_parameters(esysContext,
                 startupType);
+
+    /* Initial invocation of SAPI to prepare the command buffer with parameters */
     r = Tss2_Sys_Startup_Prepare(esysContext->sys,
                 startupType);
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error async Startup");
-        return r;
-    }
+    return_state_if_error(r, _ESYS_STATE_INIT, "SAPI Prepare returned error.");
+    /* Trigger execution and finish the async invocation */
     r = Tss2_Sys_ExecuteAsync(esysContext->sys);
-    return_if_error(r, "Finish (Execute Async)");
+    return_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Finish (Execute Async)");
 
     esysContext->state = _ESYS_STATE_SENT;
 
@@ -157,49 +158,65 @@
     ESYS_CONTEXT *esysContext)
 {
     LOG_TRACE("complete");
+    TSS2_RC r;
     if (esysContext == NULL) {
         LOG_ERROR("esyscontext is NULL.");
         return TSS2_ESYS_RC_BAD_REFERENCE;
     }
+
+    /* Check for correct sequence and set sequence to irregular for now */
     if (esysContext->state != _ESYS_STATE_SENT) {
         LOG_ERROR("Esys called in bad sequence.");
         return TSS2_ESYS_RC_BAD_SEQUENCE;
     }
-    TSS2_RC r;
+    esysContext->state = _ESYS_STATE_INTERNALERROR;
+
+    /*Receive the TPM response and handle resubmissions if necessary. */
     r = Tss2_Sys_ExecuteFinish(esysContext->sys, esysContext->timeout);
     if ((r & ~TSS2_RC_LAYER_MASK) == TSS2_BASE_RC_TRY_AGAIN) {
         LOG_DEBUG("A layer below returned TRY_AGAIN: %" PRIx32, r);
+        esysContext->state = _ESYS_STATE_SENT;
         return r;
     }
+    /* This block handle the resubmission of TPM commands given a certain set of
+     * TPM response codes. */
     if (r == TPM2_RC_RETRY || r == TPM2_RC_TESTING || r == TPM2_RC_YIELDED) {
         LOG_DEBUG("TPM returned RETRY, TESTING or YIELDED, which triggers a "
             "resubmission: %" PRIx32, r);
         if (esysContext->submissionCount >= _ESYS_MAX_SUBMISSIONS) {
-            LOG_WARNING("Maximum number of resubmissions has been reached.");
-            esysContext->state = _ESYS_STATE_ERRORRESPONSE;
+            LOG_WARNING("Maximum number of (re)submissions has been reached.");
+            esysContext->state = _ESYS_STATE_INIT;
             return r;
         }
         esysContext->state = _ESYS_STATE_RESUBMISSION;
         r = Esys_Startup_async(esysContext,
                 esysContext->in.Startup.startupType);
         if (r != TSS2_RC_SUCCESS) {
-            LOG_ERROR("Error attempting to resubmit");
+            LOG_WARNING("Error attempting to resubmit");
+            /* We do not set esysContext->state here but inherit the most recent
+             * state of the _async function. */
             return r;
         }
         r = TSS2_ESYS_RC_TRY_AGAIN;
+        LOG_DEBUG("Resubmission initiated and returning RC_TRY_AGAIN.");
         return r;
     }
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error finish (ExecuteFinish) Startup");
+    /* The following is the "regular error" handling. */
+    if (r != TSS2_RC_SUCCESS && (r & TSS2_RC_LAYER_MASK) == 0) {
+        LOG_WARNING("Received TPM Error");
+        esysContext->state = _ESYS_STATE_INIT;
+        return r;
+    } else if (r != TSS2_RC_SUCCESS) {
+        LOG_ERROR("Received a non-TPM Error");
+        esysContext->state = _ESYS_STATE_INTERNALERROR;
         return r;
     }
     r = Tss2_Sys_Startup_Complete(esysContext->sys);
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error finish (ExecuteFinish) Startup: %" PRIx32, r);
-        esysContext->state = _ESYS_STATE_ERRORRESPONSE;
-        return r;;
-    }
-    esysContext->state = _ESYS_STATE_FINISHED;
+    return_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Received error from SAPI"
+                        " unmarshalling" );
+    esysContext->state = _ESYS_STATE_INIT;
+    LOG_DEBUG("context=%p",
+              esysContext);
 
-    return r;
+    return TSS2_RC_SUCCESS;
 }
diff --git a/src/tss2-esys/api/Esys_StirRandom.c b/src/tss2-esys/api/Esys_StirRandom.c
index 1014e04..6f49110 100644
--- a/src/tss2-esys/api/Esys_StirRandom.c
+++ b/src/tss2-esys/api/Esys_StirRandom.c
@@ -138,6 +138,7 @@
     TSS2_RC r;
     TSS2L_SYS_AUTH_COMMAND auths;
 
+    /* Check context, sequence correctness and set state to error for now */
     if (esysContext == NULL) {
         LOG_ERROR("esyscontext is NULL.");
         return TSS2_ESYS_RC_BAD_REFERENCE;
@@ -145,32 +146,36 @@
     r = iesys_check_sequence_async(esysContext);
     if (r != TSS2_RC_SUCCESS)
         return r;
-    r = check_session_feasability(shandle1, shandle2, shandle3, 0);
-    return_if_error(r, "Check session usage");
+    esysContext->state = _ESYS_STATE_INTERNALERROR;
 
+    /* Check and store input parameters */
+    r = check_session_feasability(shandle1, shandle2, shandle3, 0);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Check session usage");
     store_input_parameters(esysContext,
                 inData);
+
+    /* Initial invocation of SAPI to prepare the command buffer with parameters */
     r = Tss2_Sys_StirRandom_Prepare(esysContext->sys,
                 inData);
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error async StirRandom");
-        return r;
-    }
+    return_state_if_error(r, _ESYS_STATE_INIT, "SAPI Prepare returned error.");
+
+    /* Calculate the cpHash Values */
     r = init_session_tab(esysContext, shandle1, shandle2, shandle3);
-    return_if_error(r, "Initialize session resources");
-
+    return_state_if_error(r, _ESYS_STATE_INIT, "Initialize session resources");
     iesys_compute_session_value(esysContext->session_tab[0], NULL, NULL);
-    r = iesys_gen_auths(esysContext, NULL, NULL, NULL, &auths);
-    return_if_error(r, "Error in computation of auth values");
+    iesys_compute_session_value(esysContext->session_tab[1], NULL, NULL);
+    iesys_compute_session_value(esysContext->session_tab[2], NULL, NULL);
 
+    /* Generate the auth values and set them in the SAPI command buffer */
+    r = iesys_gen_auths(esysContext, NULL, NULL, NULL, &auths);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Error in computation of auth values");
     esysContext->authsCount = auths.count;
     r = Tss2_Sys_SetCmdAuths(esysContext->sys, &auths);
-    if (r != TSS2_RC_SUCCESS) {
-        return r;
-    }
+    return_state_if_error(r, _ESYS_STATE_INIT, "SAPI error on SetCmdAuths");
 
+    /* Trigger execution and finish the async invocation */
     r = Tss2_Sys_ExecuteAsync(esysContext->sys);
-    return_if_error(r, "Finish (Execute Async)");
+    return_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Finish (Execute Async)");
 
     esysContext->state = _ESYS_STATE_SENT;
 
@@ -194,26 +199,34 @@
     ESYS_CONTEXT *esysContext)
 {
     LOG_TRACE("complete");
+    TSS2_RC r;
     if (esysContext == NULL) {
         LOG_ERROR("esyscontext is NULL.");
         return TSS2_ESYS_RC_BAD_REFERENCE;
     }
+
+    /* Check for correct sequence and set sequence to irregular for now */
     if (esysContext->state != _ESYS_STATE_SENT) {
         LOG_ERROR("Esys called in bad sequence.");
         return TSS2_ESYS_RC_BAD_SEQUENCE;
     }
-    TSS2_RC r;
+    esysContext->state = _ESYS_STATE_INTERNALERROR;
+
+    /*Receive the TPM response and handle resubmissions if necessary. */
     r = Tss2_Sys_ExecuteFinish(esysContext->sys, esysContext->timeout);
     if ((r & ~TSS2_RC_LAYER_MASK) == TSS2_BASE_RC_TRY_AGAIN) {
         LOG_DEBUG("A layer below returned TRY_AGAIN: %" PRIx32, r);
+        esysContext->state = _ESYS_STATE_SENT;
         return r;
     }
+    /* This block handle the resubmission of TPM commands given a certain set of
+     * TPM response codes. */
     if (r == TPM2_RC_RETRY || r == TPM2_RC_TESTING || r == TPM2_RC_YIELDED) {
         LOG_DEBUG("TPM returned RETRY, TESTING or YIELDED, which triggers a "
             "resubmission: %" PRIx32, r);
         if (esysContext->submissionCount >= _ESYS_MAX_SUBMISSIONS) {
-            LOG_WARNING("Maximum number of resubmissions has been reached.");
-            esysContext->state = _ESYS_STATE_ERRORRESPONSE;
+            LOG_WARNING("Maximum number of (re)submissions has been reached.");
+            esysContext->state = _ESYS_STATE_INIT;
             return r;
         }
         esysContext->state = _ESYS_STATE_RESUBMISSION;
@@ -223,33 +236,42 @@
                 esysContext->session_type[2],
                 esysContext->in.StirRandom.inData);
         if (r != TSS2_RC_SUCCESS) {
-            LOG_ERROR("Error attempting to resubmit");
+            LOG_WARNING("Error attempting to resubmit");
+            /* We do not set esysContext->state here but inherit the most recent
+             * state of the _async function. */
             return r;
         }
         r = TSS2_ESYS_RC_TRY_AGAIN;
+        LOG_DEBUG("Resubmission initiated and returning RC_TRY_AGAIN.");
         return r;
     }
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error finish (ExecuteFinish) StirRandom");
+    /* The following is the "regular error" handling. */
+    if (r != TSS2_RC_SUCCESS && (r & TSS2_RC_LAYER_MASK) == 0) {
+        LOG_WARNING("Received TPM Error");
+        esysContext->state = _ESYS_STATE_INIT;
+        return r;
+    } else if (r != TSS2_RC_SUCCESS) {
+        LOG_ERROR("Received a non-TPM Error");
+        esysContext->state = _ESYS_STATE_INTERNALERROR;
         return r;
     }
+
     /*
      * Now the verification of the response (hmac check) and if necessary the
-     * parameter decryption have to be done
+     * parameter decryption have to be done.
      */
     r = iesys_check_response(esysContext);
-    return_if_error(r, "Error: check response");
+    return_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Error: check response");
     /*
      * After the verification of the response we call the complete function
      * to deliver the result.
      */
     r = Tss2_Sys_StirRandom_Complete(esysContext->sys);
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error finish (ExecuteFinish) StirRandom: %" PRIx32, r);
-        esysContext->state = _ESYS_STATE_ERRORRESPONSE;
-        return r;;
-    }
-    esysContext->state = _ESYS_STATE_FINISHED;
+    return_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Received error from SAPI"
+                        " unmarshalling" );
+    esysContext->state = _ESYS_STATE_INIT;
+    LOG_DEBUG("context=%p",
+              esysContext);
 
-    return r;
+    return TSS2_RC_SUCCESS;
 }
diff --git a/src/tss2-esys/api/Esys_TestParms.c b/src/tss2-esys/api/Esys_TestParms.c
index ac959db..382aa41 100644
--- a/src/tss2-esys/api/Esys_TestParms.c
+++ b/src/tss2-esys/api/Esys_TestParms.c
@@ -138,6 +138,7 @@
     TSS2_RC r;
     TSS2L_SYS_AUTH_COMMAND auths;
 
+    /* Check context, sequence correctness and set state to error for now */
     if (esysContext == NULL) {
         LOG_ERROR("esyscontext is NULL.");
         return TSS2_ESYS_RC_BAD_REFERENCE;
@@ -145,32 +146,36 @@
     r = iesys_check_sequence_async(esysContext);
     if (r != TSS2_RC_SUCCESS)
         return r;
-    r = check_session_feasability(shandle1, shandle2, shandle3, 0);
-    return_if_error(r, "Check session usage");
+    esysContext->state = _ESYS_STATE_INTERNALERROR;
 
+    /* Check and store input parameters */
+    r = check_session_feasability(shandle1, shandle2, shandle3, 0);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Check session usage");
     store_input_parameters(esysContext,
                 parameters);
+
+    /* Initial invocation of SAPI to prepare the command buffer with parameters */
     r = Tss2_Sys_TestParms_Prepare(esysContext->sys,
                 parameters);
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error async TestParms");
-        return r;
-    }
+    return_state_if_error(r, _ESYS_STATE_INIT, "SAPI Prepare returned error.");
+
+    /* Calculate the cpHash Values */
     r = init_session_tab(esysContext, shandle1, shandle2, shandle3);
-    return_if_error(r, "Initialize session resources");
-
+    return_state_if_error(r, _ESYS_STATE_INIT, "Initialize session resources");
     iesys_compute_session_value(esysContext->session_tab[0], NULL, NULL);
-    r = iesys_gen_auths(esysContext, NULL, NULL, NULL, &auths);
-    return_if_error(r, "Error in computation of auth values");
+    iesys_compute_session_value(esysContext->session_tab[1], NULL, NULL);
+    iesys_compute_session_value(esysContext->session_tab[2], NULL, NULL);
 
+    /* Generate the auth values and set them in the SAPI command buffer */
+    r = iesys_gen_auths(esysContext, NULL, NULL, NULL, &auths);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Error in computation of auth values");
     esysContext->authsCount = auths.count;
     r = Tss2_Sys_SetCmdAuths(esysContext->sys, &auths);
-    if (r != TSS2_RC_SUCCESS) {
-        return r;
-    }
+    return_state_if_error(r, _ESYS_STATE_INIT, "SAPI error on SetCmdAuths");
 
+    /* Trigger execution and finish the async invocation */
     r = Tss2_Sys_ExecuteAsync(esysContext->sys);
-    return_if_error(r, "Finish (Execute Async)");
+    return_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Finish (Execute Async)");
 
     esysContext->state = _ESYS_STATE_SENT;
 
@@ -194,26 +199,34 @@
     ESYS_CONTEXT *esysContext)
 {
     LOG_TRACE("complete");
+    TSS2_RC r;
     if (esysContext == NULL) {
         LOG_ERROR("esyscontext is NULL.");
         return TSS2_ESYS_RC_BAD_REFERENCE;
     }
+
+    /* Check for correct sequence and set sequence to irregular for now */
     if (esysContext->state != _ESYS_STATE_SENT) {
         LOG_ERROR("Esys called in bad sequence.");
         return TSS2_ESYS_RC_BAD_SEQUENCE;
     }
-    TSS2_RC r;
+    esysContext->state = _ESYS_STATE_INTERNALERROR;
+
+    /*Receive the TPM response and handle resubmissions if necessary. */
     r = Tss2_Sys_ExecuteFinish(esysContext->sys, esysContext->timeout);
     if ((r & ~TSS2_RC_LAYER_MASK) == TSS2_BASE_RC_TRY_AGAIN) {
         LOG_DEBUG("A layer below returned TRY_AGAIN: %" PRIx32, r);
+        esysContext->state = _ESYS_STATE_SENT;
         return r;
     }
+    /* This block handle the resubmission of TPM commands given a certain set of
+     * TPM response codes. */
     if (r == TPM2_RC_RETRY || r == TPM2_RC_TESTING || r == TPM2_RC_YIELDED) {
         LOG_DEBUG("TPM returned RETRY, TESTING or YIELDED, which triggers a "
             "resubmission: %" PRIx32, r);
         if (esysContext->submissionCount >= _ESYS_MAX_SUBMISSIONS) {
-            LOG_WARNING("Maximum number of resubmissions has been reached.");
-            esysContext->state = _ESYS_STATE_ERRORRESPONSE;
+            LOG_WARNING("Maximum number of (re)submissions has been reached.");
+            esysContext->state = _ESYS_STATE_INIT;
             return r;
         }
         esysContext->state = _ESYS_STATE_RESUBMISSION;
@@ -223,33 +236,42 @@
                 esysContext->session_type[2],
                 esysContext->in.TestParms.parameters);
         if (r != TSS2_RC_SUCCESS) {
-            LOG_ERROR("Error attempting to resubmit");
+            LOG_WARNING("Error attempting to resubmit");
+            /* We do not set esysContext->state here but inherit the most recent
+             * state of the _async function. */
             return r;
         }
         r = TSS2_ESYS_RC_TRY_AGAIN;
+        LOG_DEBUG("Resubmission initiated and returning RC_TRY_AGAIN.");
         return r;
     }
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error finish (ExecuteFinish) TestParms");
+    /* The following is the "regular error" handling. */
+    if (r != TSS2_RC_SUCCESS && (r & TSS2_RC_LAYER_MASK) == 0) {
+        LOG_WARNING("Received TPM Error");
+        esysContext->state = _ESYS_STATE_INIT;
+        return r;
+    } else if (r != TSS2_RC_SUCCESS) {
+        LOG_ERROR("Received a non-TPM Error");
+        esysContext->state = _ESYS_STATE_INTERNALERROR;
         return r;
     }
+
     /*
      * Now the verification of the response (hmac check) and if necessary the
-     * parameter decryption have to be done
+     * parameter decryption have to be done.
      */
     r = iesys_check_response(esysContext);
-    return_if_error(r, "Error: check response");
+    return_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Error: check response");
     /*
      * After the verification of the response we call the complete function
      * to deliver the result.
      */
     r = Tss2_Sys_TestParms_Complete(esysContext->sys);
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error finish (ExecuteFinish) TestParms: %" PRIx32, r);
-        esysContext->state = _ESYS_STATE_ERRORRESPONSE;
-        return r;;
-    }
-    esysContext->state = _ESYS_STATE_FINISHED;
+    return_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Received error from SAPI"
+                        " unmarshalling" );
+    esysContext->state = _ESYS_STATE_INIT;
+    LOG_DEBUG("context=%p",
+              esysContext);
 
-    return r;
+    return TSS2_RC_SUCCESS;
 }
diff --git a/src/tss2-esys/api/Esys_Unseal.c b/src/tss2-esys/api/Esys_Unseal.c
index 08d6637..131eee4 100644
--- a/src/tss2-esys/api/Esys_Unseal.c
+++ b/src/tss2-esys/api/Esys_Unseal.c
@@ -139,6 +139,7 @@
     TSS2L_SYS_AUTH_COMMAND auths;
     RSRC_NODE_T *itemHandleNode;
 
+    /* Check context, sequence correctness and set state to error for now */
     if (esysContext == NULL) {
         LOG_ERROR("esyscontext is NULL.");
         return TSS2_ESYS_RC_BAD_REFERENCE;
@@ -146,35 +147,40 @@
     r = iesys_check_sequence_async(esysContext);
     if (r != TSS2_RC_SUCCESS)
         return r;
-    r = check_session_feasability(shandle1, shandle2, shandle3, 1);
-    return_if_error(r, "Check session usage");
+    esysContext->state = _ESYS_STATE_INTERNALERROR;
 
+    /* Check and store input parameters */
+    r = check_session_feasability(shandle1, shandle2, shandle3, 1);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Check session usage");
     store_input_parameters(esysContext, itemHandle);
+
+    /* Retrieve the metadata objects for provided handles */
     r = esys_GetResourceObject(esysContext, itemHandle, &itemHandleNode);
-    if (r != TPM2_RC_SUCCESS)
-        return r;
+    return_state_if_error(r, _ESYS_STATE_INIT, "itemHandle unknown.");
+
+    /* Initial invocation of SAPI to prepare the command buffer with parameters */
     r = Tss2_Sys_Unseal_Prepare(esysContext->sys,
                 (itemHandleNode == NULL) ? TPM2_RH_NULL : itemHandleNode->rsrc.handle);
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error async Unseal");
-        return r;
-    }
-    r = init_session_tab(esysContext, shandle1, shandle2, shandle3);
-    return_if_error(r, "Initialize session resources");
+    return_state_if_error(r, _ESYS_STATE_INIT, "SAPI Prepare returned error.");
 
+    /* Calculate the cpHash Values */
+    r = init_session_tab(esysContext, shandle1, shandle2, shandle3);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Initialize session resources");
     iesys_compute_session_value(esysContext->session_tab[0],
                 &itemHandleNode->rsrc.name, &itemHandleNode->auth);
-    r = iesys_gen_auths(esysContext, itemHandleNode, NULL, NULL, &auths);
-    return_if_error(r, "Error in computation of auth values");
+    iesys_compute_session_value(esysContext->session_tab[1], NULL, NULL);
+    iesys_compute_session_value(esysContext->session_tab[2], NULL, NULL);
 
+    /* Generate the auth values and set them in the SAPI command buffer */
+    r = iesys_gen_auths(esysContext, itemHandleNode, NULL, NULL, &auths);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Error in computation of auth values");
     esysContext->authsCount = auths.count;
     r = Tss2_Sys_SetCmdAuths(esysContext->sys, &auths);
-    if (r != TSS2_RC_SUCCESS) {
-        return r;
-    }
+    return_state_if_error(r, _ESYS_STATE_INIT, "SAPI error on SetCmdAuths");
 
+    /* Trigger execution and finish the async invocation */
     r = Tss2_Sys_ExecuteAsync(esysContext->sys);
-    return_if_error(r, "Finish (Execute Async)");
+    return_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Finish (Execute Async)");
 
     esysContext->state = _ESYS_STATE_SENT;
 
@@ -201,32 +207,42 @@
     TPM2B_SENSITIVE_DATA **outData)
 {
     LOG_TRACE("complete");
+    TSS2_RC r;
     if (esysContext == NULL) {
         LOG_ERROR("esyscontext is NULL.");
         return TSS2_ESYS_RC_BAD_REFERENCE;
     }
+
+    /* Check for correct sequence and set sequence to irregular for now */
     if (esysContext->state != _ESYS_STATE_SENT) {
         LOG_ERROR("Esys called in bad sequence.");
         return TSS2_ESYS_RC_BAD_SEQUENCE;
     }
-    TSS2_RC r;
+    esysContext->state = _ESYS_STATE_INTERNALERROR;
+
+    /* Allocate memory for response parameters */
     if (outData != NULL) {
         *outData = calloc(sizeof(TPM2B_SENSITIVE_DATA), 1);
         if (*outData == NULL) {
             return_error(TSS2_ESYS_RC_MEMORY, "Out of memory");
         }
     }
+
+    /*Receive the TPM response and handle resubmissions if necessary. */
     r = Tss2_Sys_ExecuteFinish(esysContext->sys, esysContext->timeout);
     if ((r & ~TSS2_RC_LAYER_MASK) == TSS2_BASE_RC_TRY_AGAIN) {
         LOG_DEBUG("A layer below returned TRY_AGAIN: %" PRIx32, r);
+        esysContext->state = _ESYS_STATE_SENT;
         goto error_cleanup;
     }
+    /* This block handle the resubmission of TPM commands given a certain set of
+     * TPM response codes. */
     if (r == TPM2_RC_RETRY || r == TPM2_RC_TESTING || r == TPM2_RC_YIELDED) {
         LOG_DEBUG("TPM returned RETRY, TESTING or YIELDED, which triggers a "
             "resubmission: %" PRIx32, r);
         if (esysContext->submissionCount >= _ESYS_MAX_SUBMISSIONS) {
-            LOG_WARNING("Maximum number of resubmissions has been reached.");
-            esysContext->state = _ESYS_STATE_ERRORRESPONSE;
+            LOG_WARNING("Maximum number of (re)submissions has been reached.");
+            esysContext->state = _ESYS_STATE_INIT;
             goto error_cleanup;
         }
         esysContext->state = _ESYS_STATE_RESUBMISSION;
@@ -236,22 +252,32 @@
                 esysContext->session_type[1],
                 esysContext->session_type[2]);
         if (r != TSS2_RC_SUCCESS) {
-            LOG_ERROR("Error attempting to resubmit");
+            LOG_WARNING("Error attempting to resubmit");
+            /* We do not set esysContext->state here but inherit the most recent
+             * state of the _async function. */
             goto error_cleanup;
         }
         r = TSS2_ESYS_RC_TRY_AGAIN;
+        LOG_DEBUG("Resubmission initiated and returning RC_TRY_AGAIN.");
         goto error_cleanup;
     }
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error finish (ExecuteFinish) Unseal");
+    /* The following is the "regular error" handling. */
+    if (r != TSS2_RC_SUCCESS && (r & TSS2_RC_LAYER_MASK) == 0) {
+        LOG_WARNING("Received TPM Error");
+        esysContext->state = _ESYS_STATE_INIT;
+        goto error_cleanup;
+    } else if (r != TSS2_RC_SUCCESS) {
+        LOG_ERROR("Received a non-TPM Error");
+        esysContext->state = _ESYS_STATE_INTERNALERROR;
         goto error_cleanup;
     }
+
     /*
      * Now the verification of the response (hmac check) and if necessary the
-     * parameter decryption have to be done
+     * parameter decryption have to be done.
      */
     r = iesys_check_response(esysContext);
-    goto_if_error(r, "Error: check response",
+    goto_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Error: check response",
                       error_cleanup);
     /*
      * After the verification of the response we call the complete function
@@ -259,17 +285,17 @@
      */
     r = Tss2_Sys_Unseal_Complete(esysContext->sys,
                 (outData != NULL) ? *outData : NULL);
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error finish (ExecuteFinish) Unseal: %" PRIx32, r);
-        esysContext->state = _ESYS_STATE_ERRORRESPONSE;
-        goto error_cleanup;;
-    }
-    esysContext->state = _ESYS_STATE_FINISHED;
+    goto_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Received error from SAPI"
+                        " unmarshalling" ,error_cleanup);
+    esysContext->state = _ESYS_STATE_INIT;
+    LOG_DEBUG("context=%p, outData=%p",
+              esysContext, outData);
 
-    return r;
+    return TSS2_RC_SUCCESS;
 
 error_cleanup:
     if (outData != NULL)
         SAFE_FREE(*outData);
+
     return r;
 }
diff --git a/src/tss2-esys/api/Esys_Vendor_TCG_Test.c b/src/tss2-esys/api/Esys_Vendor_TCG_Test.c
index 645a706..6a256e4 100644
--- a/src/tss2-esys/api/Esys_Vendor_TCG_Test.c
+++ b/src/tss2-esys/api/Esys_Vendor_TCG_Test.c
@@ -142,6 +142,7 @@
     TSS2_RC r;
     TSS2L_SYS_AUTH_COMMAND auths;
 
+    /* Check context, sequence correctness and set state to error for now */
     if (esysContext == NULL) {
         LOG_ERROR("esyscontext is NULL.");
         return TSS2_ESYS_RC_BAD_REFERENCE;
@@ -149,32 +150,36 @@
     r = iesys_check_sequence_async(esysContext);
     if (r != TSS2_RC_SUCCESS)
         return r;
-    r = check_session_feasability(shandle1, shandle2, shandle3, 0);
-    return_if_error(r, "Check session usage");
+    esysContext->state = _ESYS_STATE_INTERNALERROR;
 
+    /* Check and store input parameters */
+    r = check_session_feasability(shandle1, shandle2, shandle3, 0);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Check session usage");
     store_input_parameters(esysContext,
                 inputData);
+
+    /* Initial invocation of SAPI to prepare the command buffer with parameters */
     r = Tss2_Sys_Vendor_TCG_Test_Prepare(esysContext->sys,
                 inputData);
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error async Vendor_TCG_Test");
-        return r;
-    }
+    return_state_if_error(r, _ESYS_STATE_INIT, "SAPI Prepare returned error.");
+
+    /* Calculate the cpHash Values */
     r = init_session_tab(esysContext, shandle1, shandle2, shandle3);
-    return_if_error(r, "Initialize session resources");
-
+    return_state_if_error(r, _ESYS_STATE_INIT, "Initialize session resources");
     iesys_compute_session_value(esysContext->session_tab[0], NULL, NULL);
-    r = iesys_gen_auths(esysContext, NULL, NULL, NULL, &auths);
-    return_if_error(r, "Error in computation of auth values");
+    iesys_compute_session_value(esysContext->session_tab[1], NULL, NULL);
+    iesys_compute_session_value(esysContext->session_tab[2], NULL, NULL);
 
+    /* Generate the auth values and set them in the SAPI command buffer */
+    r = iesys_gen_auths(esysContext, NULL, NULL, NULL, &auths);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Error in computation of auth values");
     esysContext->authsCount = auths.count;
     r = Tss2_Sys_SetCmdAuths(esysContext->sys, &auths);
-    if (r != TSS2_RC_SUCCESS) {
-        return r;
-    }
+    return_state_if_error(r, _ESYS_STATE_INIT, "SAPI error on SetCmdAuths");
 
+    /* Trigger execution and finish the async invocation */
     r = Tss2_Sys_ExecuteAsync(esysContext->sys);
-    return_if_error(r, "Finish (Execute Async)");
+    return_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Finish (Execute Async)");
 
     esysContext->state = _ESYS_STATE_SENT;
 
@@ -201,32 +206,42 @@
     TPM2B_DATA **outputData)
 {
     LOG_TRACE("complete");
+    TSS2_RC r;
     if (esysContext == NULL) {
         LOG_ERROR("esyscontext is NULL.");
         return TSS2_ESYS_RC_BAD_REFERENCE;
     }
+
+    /* Check for correct sequence and set sequence to irregular for now */
     if (esysContext->state != _ESYS_STATE_SENT) {
         LOG_ERROR("Esys called in bad sequence.");
         return TSS2_ESYS_RC_BAD_SEQUENCE;
     }
-    TSS2_RC r;
+    esysContext->state = _ESYS_STATE_INTERNALERROR;
+
+    /* Allocate memory for response parameters */
     if (outputData != NULL) {
         *outputData = calloc(sizeof(TPM2B_DATA), 1);
         if (*outputData == NULL) {
             return_error(TSS2_ESYS_RC_MEMORY, "Out of memory");
         }
     }
+
+    /*Receive the TPM response and handle resubmissions if necessary. */
     r = Tss2_Sys_ExecuteFinish(esysContext->sys, esysContext->timeout);
     if ((r & ~TSS2_RC_LAYER_MASK) == TSS2_BASE_RC_TRY_AGAIN) {
         LOG_DEBUG("A layer below returned TRY_AGAIN: %" PRIx32, r);
+        esysContext->state = _ESYS_STATE_SENT;
         goto error_cleanup;
     }
+    /* This block handle the resubmission of TPM commands given a certain set of
+     * TPM response codes. */
     if (r == TPM2_RC_RETRY || r == TPM2_RC_TESTING || r == TPM2_RC_YIELDED) {
         LOG_DEBUG("TPM returned RETRY, TESTING or YIELDED, which triggers a "
             "resubmission: %" PRIx32, r);
         if (esysContext->submissionCount >= _ESYS_MAX_SUBMISSIONS) {
-            LOG_WARNING("Maximum number of resubmissions has been reached.");
-            esysContext->state = _ESYS_STATE_ERRORRESPONSE;
+            LOG_WARNING("Maximum number of (re)submissions has been reached.");
+            esysContext->state = _ESYS_STATE_INIT;
             goto error_cleanup;
         }
         esysContext->state = _ESYS_STATE_RESUBMISSION;
@@ -236,22 +251,32 @@
                 esysContext->session_type[2],
                 esysContext->in.Vendor_TCG_Test.inputData);
         if (r != TSS2_RC_SUCCESS) {
-            LOG_ERROR("Error attempting to resubmit");
+            LOG_WARNING("Error attempting to resubmit");
+            /* We do not set esysContext->state here but inherit the most recent
+             * state of the _async function. */
             goto error_cleanup;
         }
         r = TSS2_ESYS_RC_TRY_AGAIN;
+        LOG_DEBUG("Resubmission initiated and returning RC_TRY_AGAIN.");
         goto error_cleanup;
     }
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error finish (ExecuteFinish) Vendor_TCG_Test");
+    /* The following is the "regular error" handling. */
+    if (r != TSS2_RC_SUCCESS && (r & TSS2_RC_LAYER_MASK) == 0) {
+        LOG_WARNING("Received TPM Error");
+        esysContext->state = _ESYS_STATE_INIT;
+        goto error_cleanup;
+    } else if (r != TSS2_RC_SUCCESS) {
+        LOG_ERROR("Received a non-TPM Error");
+        esysContext->state = _ESYS_STATE_INTERNALERROR;
         goto error_cleanup;
     }
+
     /*
      * Now the verification of the response (hmac check) and if necessary the
-     * parameter decryption have to be done
+     * parameter decryption have to be done.
      */
     r = iesys_check_response(esysContext);
-    goto_if_error(r, "Error: check response",
+    goto_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Error: check response",
                       error_cleanup);
     /*
      * After the verification of the response we call the complete function
@@ -259,17 +284,17 @@
      */
     r = Tss2_Sys_Vendor_TCG_Test_Complete(esysContext->sys,
                 (outputData != NULL) ? *outputData : NULL);
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error finish (ExecuteFinish) Vendor_TCG_Test: %" PRIx32, r);
-        esysContext->state = _ESYS_STATE_ERRORRESPONSE;
-        goto error_cleanup;;
-    }
-    esysContext->state = _ESYS_STATE_FINISHED;
+    goto_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Received error from SAPI"
+                        " unmarshalling" ,error_cleanup);
+    esysContext->state = _ESYS_STATE_INIT;
+    LOG_DEBUG("context=%p, outputData=%p",
+              esysContext, outputData);
 
-    return r;
+    return TSS2_RC_SUCCESS;
 
 error_cleanup:
     if (outputData != NULL)
         SAFE_FREE(*outputData);
+
     return r;
 }
diff --git a/src/tss2-esys/api/Esys_VerifySignature.c b/src/tss2-esys/api/Esys_VerifySignature.c
index 4e1735b..94cf07b 100644
--- a/src/tss2-esys/api/Esys_VerifySignature.c
+++ b/src/tss2-esys/api/Esys_VerifySignature.c
@@ -165,6 +165,7 @@
     TSS2L_SYS_AUTH_COMMAND auths;
     RSRC_NODE_T *keyHandleNode;
 
+    /* Check context, sequence correctness and set state to error for now */
     if (esysContext == NULL) {
         LOG_ERROR("esyscontext is NULL.");
         return TSS2_ESYS_RC_BAD_REFERENCE;
@@ -172,40 +173,43 @@
     r = iesys_check_sequence_async(esysContext);
     if (r != TSS2_RC_SUCCESS)
         return r;
-    r = check_session_feasability(shandle1, shandle2, shandle3, 0);
-    return_if_error(r, "Check session usage");
+    esysContext->state = _ESYS_STATE_INTERNALERROR;
 
+    /* Check and store input parameters */
+    r = check_session_feasability(shandle1, shandle2, shandle3, 0);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Check session usage");
     store_input_parameters(esysContext, keyHandle,
                 digest,
                 signature);
+
+    /* Retrieve the metadata objects for provided handles */
     r = esys_GetResourceObject(esysContext, keyHandle, &keyHandleNode);
-    if (r != TPM2_RC_SUCCESS)
-        return r;
+    return_state_if_error(r, _ESYS_STATE_INIT, "keyHandle unknown.");
+
+    /* Initial invocation of SAPI to prepare the command buffer with parameters */
     r = Tss2_Sys_VerifySignature_Prepare(esysContext->sys,
                 (keyHandleNode == NULL) ? TPM2_RH_NULL : keyHandleNode->rsrc.handle,
                 digest,
                 signature);
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error async VerifySignature");
-        return r;
-    }
-    r = init_session_tab(esysContext, shandle1, shandle2, shandle3);
-    return_if_error(r, "Initialize session resources");
+    return_state_if_error(r, _ESYS_STATE_INIT, "SAPI Prepare returned error.");
 
+    /* Calculate the cpHash Values */
+    r = init_session_tab(esysContext, shandle1, shandle2, shandle3);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Initialize session resources");
     iesys_compute_session_value(esysContext->session_tab[0], NULL, NULL);
     iesys_compute_session_value(esysContext->session_tab[1], NULL, NULL);
     iesys_compute_session_value(esysContext->session_tab[2], NULL, NULL);
-    r = iesys_gen_auths(esysContext, keyHandleNode, NULL, NULL, &auths);
-    return_if_error(r, "Error in computation of auth values");
 
+    /* Generate the auth values and set them in the SAPI command buffer */
+    r = iesys_gen_auths(esysContext, keyHandleNode, NULL, NULL, &auths);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Error in computation of auth values");
     esysContext->authsCount = auths.count;
     r = Tss2_Sys_SetCmdAuths(esysContext->sys, &auths);
-    if (r != TSS2_RC_SUCCESS) {
-        return r;
-    }
+    return_state_if_error(r, _ESYS_STATE_INIT, "SAPI error on SetCmdAuths");
 
+    /* Trigger execution and finish the async invocation */
     r = Tss2_Sys_ExecuteAsync(esysContext->sys);
-    return_if_error(r, "Finish (Execute Async)");
+    return_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Finish (Execute Async)");
 
     esysContext->state = _ESYS_STATE_SENT;
 
@@ -232,32 +236,42 @@
     TPMT_TK_VERIFIED **validation)
 {
     LOG_TRACE("complete");
+    TSS2_RC r;
     if (esysContext == NULL) {
         LOG_ERROR("esyscontext is NULL.");
         return TSS2_ESYS_RC_BAD_REFERENCE;
     }
+
+    /* Check for correct sequence and set sequence to irregular for now */
     if (esysContext->state != _ESYS_STATE_SENT) {
         LOG_ERROR("Esys called in bad sequence.");
         return TSS2_ESYS_RC_BAD_SEQUENCE;
     }
-    TSS2_RC r;
+    esysContext->state = _ESYS_STATE_INTERNALERROR;
+
+    /* Allocate memory for response parameters */
     if (validation != NULL) {
         *validation = calloc(sizeof(TPMT_TK_VERIFIED), 1);
         if (*validation == NULL) {
             return_error(TSS2_ESYS_RC_MEMORY, "Out of memory");
         }
     }
+
+    /*Receive the TPM response and handle resubmissions if necessary. */
     r = Tss2_Sys_ExecuteFinish(esysContext->sys, esysContext->timeout);
     if ((r & ~TSS2_RC_LAYER_MASK) == TSS2_BASE_RC_TRY_AGAIN) {
         LOG_DEBUG("A layer below returned TRY_AGAIN: %" PRIx32, r);
+        esysContext->state = _ESYS_STATE_SENT;
         goto error_cleanup;
     }
+    /* This block handle the resubmission of TPM commands given a certain set of
+     * TPM response codes. */
     if (r == TPM2_RC_RETRY || r == TPM2_RC_TESTING || r == TPM2_RC_YIELDED) {
         LOG_DEBUG("TPM returned RETRY, TESTING or YIELDED, which triggers a "
             "resubmission: %" PRIx32, r);
         if (esysContext->submissionCount >= _ESYS_MAX_SUBMISSIONS) {
-            LOG_WARNING("Maximum number of resubmissions has been reached.");
-            esysContext->state = _ESYS_STATE_ERRORRESPONSE;
+            LOG_WARNING("Maximum number of (re)submissions has been reached.");
+            esysContext->state = _ESYS_STATE_INIT;
             goto error_cleanup;
         }
         esysContext->state = _ESYS_STATE_RESUBMISSION;
@@ -269,22 +283,32 @@
                 esysContext->in.VerifySignature.digest,
                 esysContext->in.VerifySignature.signature);
         if (r != TSS2_RC_SUCCESS) {
-            LOG_ERROR("Error attempting to resubmit");
+            LOG_WARNING("Error attempting to resubmit");
+            /* We do not set esysContext->state here but inherit the most recent
+             * state of the _async function. */
             goto error_cleanup;
         }
         r = TSS2_ESYS_RC_TRY_AGAIN;
+        LOG_DEBUG("Resubmission initiated and returning RC_TRY_AGAIN.");
         goto error_cleanup;
     }
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error finish (ExecuteFinish) VerifySignature");
+    /* The following is the "regular error" handling. */
+    if (r != TSS2_RC_SUCCESS && (r & TSS2_RC_LAYER_MASK) == 0) {
+        LOG_WARNING("Received TPM Error");
+        esysContext->state = _ESYS_STATE_INIT;
+        goto error_cleanup;
+    } else if (r != TSS2_RC_SUCCESS) {
+        LOG_ERROR("Received a non-TPM Error");
+        esysContext->state = _ESYS_STATE_INTERNALERROR;
         goto error_cleanup;
     }
+
     /*
      * Now the verification of the response (hmac check) and if necessary the
-     * parameter decryption have to be done
+     * parameter decryption have to be done.
      */
     r = iesys_check_response(esysContext);
-    goto_if_error(r, "Error: check response",
+    goto_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Error: check response",
                       error_cleanup);
     /*
      * After the verification of the response we call the complete function
@@ -292,17 +316,17 @@
      */
     r = Tss2_Sys_VerifySignature_Complete(esysContext->sys,
                 (validation != NULL) ? *validation : NULL);
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error finish (ExecuteFinish) VerifySignature: %" PRIx32, r);
-        esysContext->state = _ESYS_STATE_ERRORRESPONSE;
-        goto error_cleanup;;
-    }
-    esysContext->state = _ESYS_STATE_FINISHED;
+    goto_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Received error from SAPI"
+                        " unmarshalling" ,error_cleanup);
+    esysContext->state = _ESYS_STATE_INIT;
+    LOG_DEBUG("context=%p, validation=%p",
+              esysContext, validation);
 
-    return r;
+    return TSS2_RC_SUCCESS;
 
 error_cleanup:
     if (validation != NULL)
         SAFE_FREE(*validation);
+
     return r;
 }
diff --git a/src/tss2-esys/api/Esys_ZGen_2Phase.c b/src/tss2-esys/api/Esys_ZGen_2Phase.c
index ee8b526..2c3536d 100644
--- a/src/tss2-esys/api/Esys_ZGen_2Phase.c
+++ b/src/tss2-esys/api/Esys_ZGen_2Phase.c
@@ -183,6 +183,7 @@
     TSS2L_SYS_AUTH_COMMAND auths;
     RSRC_NODE_T *keyANode;
 
+    /* Check context, sequence correctness and set state to error for now */
     if (esysContext == NULL) {
         LOG_ERROR("esyscontext is NULL.");
         return TSS2_ESYS_RC_BAD_REFERENCE;
@@ -190,45 +191,48 @@
     r = iesys_check_sequence_async(esysContext);
     if (r != TSS2_RC_SUCCESS)
         return r;
-    r = check_session_feasability(shandle1, shandle2, shandle3, 1);
-    return_if_error(r, "Check session usage");
+    esysContext->state = _ESYS_STATE_INTERNALERROR;
 
+    /* Check and store input parameters */
+    r = check_session_feasability(shandle1, shandle2, shandle3, 1);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Check session usage");
     store_input_parameters(esysContext, keyA,
                 inQsB,
                 inQeB,
                 inScheme,
                 counter);
+
+    /* Retrieve the metadata objects for provided handles */
     r = esys_GetResourceObject(esysContext, keyA, &keyANode);
-    if (r != TPM2_RC_SUCCESS)
-        return r;
+    return_state_if_error(r, _ESYS_STATE_INIT, "keyA unknown.");
+
+    /* Initial invocation of SAPI to prepare the command buffer with parameters */
     r = Tss2_Sys_ZGen_2Phase_Prepare(esysContext->sys,
                 (keyANode == NULL) ? TPM2_RH_NULL : keyANode->rsrc.handle,
                 inQsB,
                 inQeB,
                 inScheme,
                 counter);
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error async ZGen_2Phase");
-        return r;
-    }
-    r = init_session_tab(esysContext, shandle1, shandle2, shandle3);
-    return_if_error(r, "Initialize session resources");
+    return_state_if_error(r, _ESYS_STATE_INIT, "SAPI Prepare returned error.");
 
+    /* Calculate the cpHash Values */
+    r = init_session_tab(esysContext, shandle1, shandle2, shandle3);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Initialize session resources");
     iesys_compute_session_value(esysContext->session_tab[0],
                 &keyANode->rsrc.name, &keyANode->auth);
     iesys_compute_session_value(esysContext->session_tab[1], NULL, NULL);
     iesys_compute_session_value(esysContext->session_tab[2], NULL, NULL);
-    r = iesys_gen_auths(esysContext, keyANode, NULL, NULL, &auths);
-    return_if_error(r, "Error in computation of auth values");
 
+    /* Generate the auth values and set them in the SAPI command buffer */
+    r = iesys_gen_auths(esysContext, keyANode, NULL, NULL, &auths);
+    return_state_if_error(r, _ESYS_STATE_INIT, "Error in computation of auth values");
     esysContext->authsCount = auths.count;
     r = Tss2_Sys_SetCmdAuths(esysContext->sys, &auths);
-    if (r != TSS2_RC_SUCCESS) {
-        return r;
-    }
+    return_state_if_error(r, _ESYS_STATE_INIT, "SAPI error on SetCmdAuths");
 
+    /* Trigger execution and finish the async invocation */
     r = Tss2_Sys_ExecuteAsync(esysContext->sys);
-    return_if_error(r, "Finish (Execute Async)");
+    return_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Finish (Execute Async)");
 
     esysContext->state = _ESYS_STATE_SENT;
 
@@ -258,15 +262,20 @@
     TPM2B_ECC_POINT **outZ2)
 {
     LOG_TRACE("complete");
+    TSS2_RC r;
     if (esysContext == NULL) {
         LOG_ERROR("esyscontext is NULL.");
         return TSS2_ESYS_RC_BAD_REFERENCE;
     }
+
+    /* Check for correct sequence and set sequence to irregular for now */
     if (esysContext->state != _ESYS_STATE_SENT) {
         LOG_ERROR("Esys called in bad sequence.");
         return TSS2_ESYS_RC_BAD_SEQUENCE;
     }
-    TSS2_RC r;
+    esysContext->state = _ESYS_STATE_INTERNALERROR;
+
+    /* Allocate memory for response parameters */
     if (outZ1 != NULL) {
         *outZ1 = calloc(sizeof(TPM2B_ECC_POINT), 1);
         if (*outZ1 == NULL) {
@@ -279,17 +288,22 @@
             goto_error(r, TSS2_ESYS_RC_MEMORY, "Out of memory", error_cleanup);
         }
     }
+
+    /*Receive the TPM response and handle resubmissions if necessary. */
     r = Tss2_Sys_ExecuteFinish(esysContext->sys, esysContext->timeout);
     if ((r & ~TSS2_RC_LAYER_MASK) == TSS2_BASE_RC_TRY_AGAIN) {
         LOG_DEBUG("A layer below returned TRY_AGAIN: %" PRIx32, r);
+        esysContext->state = _ESYS_STATE_SENT;
         goto error_cleanup;
     }
+    /* This block handle the resubmission of TPM commands given a certain set of
+     * TPM response codes. */
     if (r == TPM2_RC_RETRY || r == TPM2_RC_TESTING || r == TPM2_RC_YIELDED) {
         LOG_DEBUG("TPM returned RETRY, TESTING or YIELDED, which triggers a "
             "resubmission: %" PRIx32, r);
         if (esysContext->submissionCount >= _ESYS_MAX_SUBMISSIONS) {
-            LOG_WARNING("Maximum number of resubmissions has been reached.");
-            esysContext->state = _ESYS_STATE_ERRORRESPONSE;
+            LOG_WARNING("Maximum number of (re)submissions has been reached.");
+            esysContext->state = _ESYS_STATE_INIT;
             goto error_cleanup;
         }
         esysContext->state = _ESYS_STATE_RESUBMISSION;
@@ -303,22 +317,32 @@
                 esysContext->in.ZGen_2Phase.inScheme,
                 esysContext->in.ZGen_2Phase.counter);
         if (r != TSS2_RC_SUCCESS) {
-            LOG_ERROR("Error attempting to resubmit");
+            LOG_WARNING("Error attempting to resubmit");
+            /* We do not set esysContext->state here but inherit the most recent
+             * state of the _async function. */
             goto error_cleanup;
         }
         r = TSS2_ESYS_RC_TRY_AGAIN;
+        LOG_DEBUG("Resubmission initiated and returning RC_TRY_AGAIN.");
         goto error_cleanup;
     }
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error finish (ExecuteFinish) ZGen_2Phase");
+    /* The following is the "regular error" handling. */
+    if (r != TSS2_RC_SUCCESS && (r & TSS2_RC_LAYER_MASK) == 0) {
+        LOG_WARNING("Received TPM Error");
+        esysContext->state = _ESYS_STATE_INIT;
+        goto error_cleanup;
+    } else if (r != TSS2_RC_SUCCESS) {
+        LOG_ERROR("Received a non-TPM Error");
+        esysContext->state = _ESYS_STATE_INTERNALERROR;
         goto error_cleanup;
     }
+
     /*
      * Now the verification of the response (hmac check) and if necessary the
-     * parameter decryption have to be done
+     * parameter decryption have to be done.
      */
     r = iesys_check_response(esysContext);
-    goto_if_error(r, "Error: check response",
+    goto_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Error: check response",
                       error_cleanup);
     /*
      * After the verification of the response we call the complete function
@@ -327,19 +351,19 @@
     r = Tss2_Sys_ZGen_2Phase_Complete(esysContext->sys,
                 (outZ1 != NULL) ? *outZ1 : NULL,
                 (outZ2 != NULL) ? *outZ2 : NULL);
-    if (r != TSS2_RC_SUCCESS) {
-        LOG_ERROR("Error finish (ExecuteFinish) ZGen_2Phase: %" PRIx32, r);
-        esysContext->state = _ESYS_STATE_ERRORRESPONSE;
-        goto error_cleanup;;
-    }
-    esysContext->state = _ESYS_STATE_FINISHED;
+    goto_state_if_error(r, _ESYS_STATE_INTERNALERROR, "Received error from SAPI"
+                        " unmarshalling" ,error_cleanup);
+    esysContext->state = _ESYS_STATE_INIT;
+    LOG_DEBUG("context=%p, outZ1=%p, outZ2=%p",
+              esysContext, outZ1, outZ2);
 
-    return r;
+    return TSS2_RC_SUCCESS;
 
 error_cleanup:
     if (outZ1 != NULL)
         SAFE_FREE(*outZ1);
     if (outZ2 != NULL)
         SAFE_FREE(*outZ2);
+
     return r;
 }
diff --git a/src/tss2-esys/esys_int.h b/src/tss2-esys/esys_int.h
index df43c61..bc9f849 100644
--- a/src/tss2-esys/esys_int.h
+++ b/src/tss2-esys/esys_int.h
@@ -1054,9 +1054,8 @@
 enum _ESYS_STATE {
     _ESYS_STATE_INIT = 0,
     _ESYS_STATE_SENT,
-    _ESYS_STATE_ERRORRESPONSE,
-    _ESYS_STATE_FINISHED,
-    _ESYS_STATE_RESUBMISSION
+    _ESYS_STATE_RESUBMISSION,
+    _ESYS_STATE_INTERNALERROR
 };
 
 struct ESYS_CONTEXT {
diff --git a/src/tss2-esys/esys_iutil.c b/src/tss2-esys/esys_iutil.c
index 77c3af1..3885a4f 100644
--- a/src/tss2-esys/esys_iutil.c
+++ b/src/tss2-esys/esys_iutil.c
@@ -909,8 +909,6 @@
     }
 
     if (esys_context->state != _ESYS_STATE_INIT &&
-        esys_context->state != _ESYS_STATE_ERRORRESPONSE &&
-        esys_context->state != _ESYS_STATE_FINISHED &&
         esys_context->state != _ESYS_STATE_RESUBMISSION) {
         LOG_ERROR("Esys called in bad sequence.");
         return TSS2_ESYS_RC_BAD_SEQUENCE;
diff --git a/src/tss2-esys/esys_iutil.h b/src/tss2-esys/esys_iutil.h
index 8776349..05824e9 100644
--- a/src/tss2-esys/esys_iutil.h
+++ b/src/tss2-esys/esys_iutil.h
@@ -49,12 +49,26 @@
         return r;  \
     }
 
+#define return_state_if_error(r,s,msg)      \
+    if (r != TSS2_RC_SUCCESS) { \
+        LOG_ERROR("%s " TPM2_ERROR_FORMAT, msg, TPM2_ERROR_TEXT(r)); \
+        esysContext->state = s; \
+        return r;  \
+    }
+
 #define return_error(r,msg) \
     { \
         LOG_ERROR("%s " TPM2_ERROR_FORMAT, msg, TPM2_ERROR_TEXT(r)); \
         return r;  \
     }
 
+#define goto_state_if_error(r,s,msg,label) \
+    if (r != TSS2_RC_SUCCESS) { \
+        LOG_ERROR("%s " TPM2_ERROR_FORMAT, msg, TPM2_ERROR_TEXT(r)); \
+        esysContext->state = s; \
+        goto label;  \
+    }
+
 #define goto_if_error(r,msg,label) \
     if (r != TSS2_RC_SUCCESS) { \
         LOG_ERROR("%s " TPM2_ERROR_FORMAT, msg, TPM2_ERROR_TEXT(r)); \
@@ -62,7 +76,7 @@
     }
 
 #define goto_error(r,v,msg,label) \
-    { r = v;                                                                \
+    { r = v;  \
       LOG_ERROR("%s " TPM2_ERROR_FORMAT, msg, TPM2_ERROR_TEXT(r)); \
       goto label; \
     }