sys: allow Tss2_Sys_Execute to be called repeatedly
Allow commands to be reissued by calling Execute or ExecuteFinish
again after a TPM returns an error. This should simplify ESAPI retry
logic in response to TPM_RC_RETRY. This behavior in described in SAPI
specification 1.1 rev 24.
Signed-off-by: Tadeusz Struk <tadeusz.struk@intel.com>
diff --git a/src/tss2-sys/api/Tss2_Sys_Execute.c b/src/tss2-sys/api/Tss2_Sys_Execute.c
index b29571c..94e9c96 100644
--- a/src/tss2-sys/api/Tss2_Sys_Execute.c
+++ b/src/tss2-sys/api/Tss2_Sys_Execute.c
@@ -5,6 +5,7 @@
***********************************************************************/
#include <inttypes.h>
+#include <string.h>
#include "tss2_tpm2_types.h"
#include "tss2_mu.h"
@@ -30,6 +31,11 @@
if (rval)
return rval;
+ /* Keep a copy of the cmd header to be able reissue the command
+ * after receiving a TPM error
+ */
+ memcpy(ctx->cmd_header, ctx->cmdBuffer, sizeof(ctx->cmd_header));
+
ctx->previousStage = CMD_STAGE_SEND_COMMAND;
return rval;
@@ -130,16 +136,21 @@
rval = ctx->rsp_header.responseCode;
- /* If we received a TPM error other than CANCELED or if we didn't
- * receive enough response bytes, reset SAPI state machine to
+ /* If didn't receive enough response bytes, reset SAPI state machine to
* CMD_STAGE_PREPARE. There's nothing else we can do for current command.
*/
if (ctx->rsp_header.responseSize < sizeof(TPM20_Header_Out)) {
ctx->previousStage = CMD_STAGE_PREPARE;
return TSS2_SYS_RC_INSUFFICIENT_RESPONSE;
}
- if (rval == TPM2_RC_CANCELED) {
+
+ /* If we received a TPM error then reset SAPI state machine to
+ * CMD_STAGE_PREPARE, and restore the command header so the command
+ * can be reissued without going through the usual *_prepare stage.
+ */
+ if (rval && rval != TPM2_RC_INITIALIZE) {
ctx->previousStage = CMD_STAGE_PREPARE;
+ memcpy(ctx->cmdBuffer, ctx->cmd_header, sizeof(ctx->cmd_header));
return rval;
}
diff --git a/src/tss2-sys/sysapi_util.h b/src/tss2-sys/sysapi_util.h
index eb5c1b2..ea5b751 100644
--- a/src/tss2-sys/sysapi_util.h
+++ b/src/tss2-sys/sysapi_util.h
@@ -40,6 +40,7 @@
TSS2_TCTI_CONTEXT *tctiContext;
UINT8 *cmdBuffer;
UINT32 maxCmdSize;
+ UINT8 cmd_header[sizeof(TPM20_Header_In)]; /* Copy of the cmd header to allow reissue */
TPM20_Header_Out rsp_header;
TPM2_CC commandCode; /* In host endian */