mirror of https://github.com/wolfSSL/wolfTPM.git
F-10829 - Set TPMA_CC flushed bit for SequenceComplete commands
parent
38b08ea8fd
commit
373a22f517
|
|
@ -16676,6 +16676,7 @@ typedef struct {
|
|||
UINT8 encDecFlags; /* Bit 0: first cmd param is TPM2B (can decrypt) */
|
||||
/* Bit 1: first rsp param is TPM2B (can encrypt) */
|
||||
/* Bit 2: first auth handle has DUP role */
|
||||
/* Bit 3: command flushes its handle (TPMA_CC.F) */
|
||||
} FWTPM_CMD_ENTRY;
|
||||
|
||||
#ifndef FWTPM_NO_PARAM_ENC
|
||||
|
|
@ -16689,6 +16690,10 @@ typedef struct {
|
|||
* a policy session, never a password or HMAC session. */
|
||||
#define FW_CMD_FLAG_AUTH_DUP 0x04
|
||||
|
||||
/* Part 3 command-description modifier reported through TPMA_CC. {F}: the
|
||||
* object or sequence named by the command's handle is flushed on success. */
|
||||
#define FW_CMD_MOD_FLUSHED 0x08
|
||||
|
||||
/* inH aH oH flags */
|
||||
static const FWTPM_CMD_ENTRY fwCmdTable[] = {
|
||||
/* --- Basic (always enabled) --- */
|
||||
|
|
@ -16754,8 +16759,8 @@ static const FWTPM_CMD_ENTRY fwCmdTable[] = {
|
|||
* SignSequenceComplete / VerifySequenceComplete, so it is never advertised
|
||||
* once the hash commands (and their sequence producers) are gated out. */
|
||||
#ifndef FWTPM_NO_HASH_CMDS
|
||||
{ TPM_CC_SequenceComplete, FwCmd_SequenceComplete, 1, 1, 0, FW_CMD_FLAG_ENC | FW_CMD_FLAG_DEC },
|
||||
{ TPM_CC_EventSequenceComplete, FwCmd_EventSequenceComplete, 2, 2, 0, FW_CMD_FLAG_ENC },
|
||||
{ TPM_CC_SequenceComplete, FwCmd_SequenceComplete, 1, 1, 0, FW_CMD_FLAG_ENC | FW_CMD_FLAG_DEC | FW_CMD_MOD_FLUSHED },
|
||||
{ TPM_CC_EventSequenceComplete, FwCmd_EventSequenceComplete, 2, 2, 0, FW_CMD_FLAG_ENC | FW_CMD_MOD_FLUSHED },
|
||||
#endif /* !FWTPM_NO_HASH_CMDS */
|
||||
/* --- ECC --- */
|
||||
#ifdef HAVE_ECC
|
||||
|
|
@ -16869,12 +16874,12 @@ static const FWTPM_CMD_ENTRY fwCmdTable[] = {
|
|||
#endif
|
||||
#ifdef WOLFTPM_MLDSA_SIGN
|
||||
{ TPM_CC_SignSequenceStart, FwCmd_SignSequenceStart, 1, 0, 1, FW_CMD_FLAG_ENC },
|
||||
{ TPM_CC_SignSequenceComplete, FwCmd_SignSequenceComplete, 2, 2, 0, FW_CMD_FLAG_ENC },
|
||||
{ TPM_CC_SignSequenceComplete, FwCmd_SignSequenceComplete, 2, 2, 0, FW_CMD_FLAG_ENC | FW_CMD_MOD_FLUSHED },
|
||||
{ TPM_CC_SignDigest, FwCmd_SignDigest, 1, 1, 0, FW_CMD_FLAG_ENC },
|
||||
#endif
|
||||
#ifdef WOLFTPM_MLDSA_VERIFY
|
||||
{ TPM_CC_VerifySequenceStart, FwCmd_VerifySequenceStart, 1, 0, 1, FW_CMD_FLAG_ENC },
|
||||
{ TPM_CC_VerifySequenceComplete, FwCmd_VerifySequenceComplete, 2, 1, 0, 0 },
|
||||
{ TPM_CC_VerifySequenceComplete, FwCmd_VerifySequenceComplete, 2, 1, 0, FW_CMD_MOD_FLUSHED },
|
||||
{ TPM_CC_VerifyDigestSignature, FwCmd_VerifyDigestSignature, 1, 0, 0, FW_CMD_FLAG_ENC },
|
||||
#endif
|
||||
};
|
||||
|
|
@ -16908,6 +16913,8 @@ static UINT32 FwGetCmdAttrsAt(int idx)
|
|||
attrs |= ((UINT32)(e->inHandleCnt) & 0x7u) << 25; /* cHandles */
|
||||
if (e->outHandleCnt > 0)
|
||||
attrs |= ((UINT32)1 << 28); /* rHandle */
|
||||
if (e->encDecFlags & FW_CMD_MOD_FLUSHED)
|
||||
attrs |= ((UINT32)1 << 24); /* flushed */
|
||||
if ((UINT32)e->cc & (UINT32)CC_VEND)
|
||||
attrs |= (UINT32)CC_VEND; /* V */
|
||||
return attrs;
|
||||
|
|
|
|||
|
|
@ -137,6 +137,14 @@ static UINT32 TpmaCcRHandle(UINT32 tpma)
|
|||
return (tpma >> 28) & 0x1u;
|
||||
}
|
||||
|
||||
#ifndef FWTPM_NO_HASH_CMDS
|
||||
/* flushed bit (handle's object/sequence is flushed on success), bit 24. */
|
||||
static UINT32 TpmaCcFlushed(UINT32 tpma)
|
||||
{
|
||||
return (tpma >> 24) & 0x1u;
|
||||
}
|
||||
#endif /* !FWTPM_NO_HASH_CMDS */
|
||||
|
||||
/* Build a TPM command header. Returns TPM2_HEADER_SIZE (10). */
|
||||
static int BuildCmdHeader(byte* buf, UINT16 tag, UINT32 totalSize, UINT32 cc)
|
||||
{
|
||||
|
|
@ -781,6 +789,107 @@ static void test_fwtpm_getcap_commands_tpma(void)
|
|||
fwtpm_pass("GetCapability(COMMANDS) TPMA_CC:", 0);
|
||||
}
|
||||
|
||||
|
||||
/* TPM_CAP_COMMANDS must set TPMA_CC.flushed for every {F} command (the
|
||||
* handle's object/sequence is flushed on success): SequenceComplete and
|
||||
* EventSequenceComplete per TPM 2.0 Part 3. Both live under the hash-command
|
||||
* group, so this check follows that gate. */
|
||||
#ifndef FWTPM_NO_HASH_CMDS
|
||||
static void test_fwtpm_getcap_commands_flushed(void)
|
||||
{
|
||||
FWTPM_CTX ctx;
|
||||
int rc, rspSize, cmdSz;
|
||||
UINT32 tpma;
|
||||
|
||||
memset(&ctx, 0, sizeof(ctx));
|
||||
rc = fwtpm_test_startup(&ctx);
|
||||
AssertIntEQ(rc, 0);
|
||||
|
||||
cmdSz = BuildCmdHeader(gCmd, TPM_ST_NO_SESSIONS, 0, TPM_CC_GetCapability);
|
||||
PutU32BE(gCmd + cmdSz, TPM_CAP_COMMANDS); cmdSz += 4;
|
||||
PutU32BE(gCmd + cmdSz, TPM_CC_SequenceComplete); cmdSz += 4;
|
||||
PutU32BE(gCmd + cmdSz, 1); cmdSz += 4;
|
||||
PutU32BE(gCmd + 2, (UINT32)cmdSz);
|
||||
|
||||
rspSize = 0;
|
||||
rc = FWTPM_ProcessCommand(&ctx, gCmd, cmdSz, gRsp, &rspSize, 0);
|
||||
AssertIntEQ(rc, TPM_RC_SUCCESS);
|
||||
AssertIntEQ(GetRspRC(gRsp), TPM_RC_SUCCESS);
|
||||
AssertIntEQ(GetU32BE(gRsp + TPM2_HEADER_SIZE + 5), 1); /* count */
|
||||
tpma = GetU32BE(gRsp + TPM2_HEADER_SIZE + 9);
|
||||
AssertIntEQ(TpmaCcToCmdCode(tpma), (UINT32)TPM_CC_SequenceComplete);
|
||||
AssertIntEQ(TpmaCcFlushed(tpma), 1);
|
||||
|
||||
cmdSz = BuildCmdHeader(gCmd, TPM_ST_NO_SESSIONS, 0, TPM_CC_GetCapability);
|
||||
PutU32BE(gCmd + cmdSz, TPM_CAP_COMMANDS); cmdSz += 4;
|
||||
PutU32BE(gCmd + cmdSz, TPM_CC_EventSequenceComplete); cmdSz += 4;
|
||||
PutU32BE(gCmd + cmdSz, 1); cmdSz += 4;
|
||||
PutU32BE(gCmd + 2, (UINT32)cmdSz);
|
||||
|
||||
rspSize = 0;
|
||||
rc = FWTPM_ProcessCommand(&ctx, gCmd, cmdSz, gRsp, &rspSize, 0);
|
||||
AssertIntEQ(rc, TPM_RC_SUCCESS);
|
||||
AssertIntEQ(GetRspRC(gRsp), TPM_RC_SUCCESS);
|
||||
AssertIntEQ(GetU32BE(gRsp + TPM2_HEADER_SIZE + 5), 1); /* count */
|
||||
tpma = GetU32BE(gRsp + TPM2_HEADER_SIZE + 9);
|
||||
AssertIntEQ(TpmaCcToCmdCode(tpma), (UINT32)TPM_CC_EventSequenceComplete);
|
||||
AssertIntEQ(TpmaCcFlushed(tpma), 1);
|
||||
|
||||
/* SequenceUpdate updates a sequence but does not complete or flush it, so
|
||||
* its flushed bit must be clear. Guards against an unconditional set. */
|
||||
cmdSz = BuildCmdHeader(gCmd, TPM_ST_NO_SESSIONS, 0, TPM_CC_GetCapability);
|
||||
PutU32BE(gCmd + cmdSz, TPM_CAP_COMMANDS); cmdSz += 4;
|
||||
PutU32BE(gCmd + cmdSz, TPM_CC_SequenceUpdate); cmdSz += 4;
|
||||
PutU32BE(gCmd + cmdSz, 1); cmdSz += 4;
|
||||
PutU32BE(gCmd + 2, (UINT32)cmdSz);
|
||||
|
||||
rspSize = 0;
|
||||
rc = FWTPM_ProcessCommand(&ctx, gCmd, cmdSz, gRsp, &rspSize, 0);
|
||||
AssertIntEQ(rc, TPM_RC_SUCCESS);
|
||||
AssertIntEQ(GetRspRC(gRsp), TPM_RC_SUCCESS);
|
||||
AssertIntEQ(GetU32BE(gRsp + TPM2_HEADER_SIZE + 5), 1); /* count */
|
||||
tpma = GetU32BE(gRsp + TPM2_HEADER_SIZE + 9);
|
||||
AssertIntEQ(TpmaCcToCmdCode(tpma), (UINT32)TPM_CC_SequenceUpdate);
|
||||
AssertIntEQ(TpmaCcFlushed(tpma), 0);
|
||||
|
||||
#ifdef WOLFTPM_MLDSA_SIGN
|
||||
/* SignSequenceComplete flushes its sign sequence on success. */
|
||||
cmdSz = BuildCmdHeader(gCmd, TPM_ST_NO_SESSIONS, 0, TPM_CC_GetCapability);
|
||||
PutU32BE(gCmd + cmdSz, TPM_CAP_COMMANDS); cmdSz += 4;
|
||||
PutU32BE(gCmd + cmdSz, TPM_CC_SignSequenceComplete); cmdSz += 4;
|
||||
PutU32BE(gCmd + cmdSz, 1); cmdSz += 4;
|
||||
PutU32BE(gCmd + 2, (UINT32)cmdSz);
|
||||
|
||||
rspSize = 0;
|
||||
rc = FWTPM_ProcessCommand(&ctx, gCmd, cmdSz, gRsp, &rspSize, 0);
|
||||
AssertIntEQ(rc, TPM_RC_SUCCESS);
|
||||
AssertIntEQ(GetRspRC(gRsp), TPM_RC_SUCCESS);
|
||||
tpma = GetU32BE(gRsp + TPM2_HEADER_SIZE + 9);
|
||||
AssertIntEQ(TpmaCcToCmdCode(tpma), (UINT32)TPM_CC_SignSequenceComplete);
|
||||
AssertIntEQ(TpmaCcFlushed(tpma), 1);
|
||||
#endif /* WOLFTPM_MLDSA_SIGN */
|
||||
#ifdef WOLFTPM_MLDSA_VERIFY
|
||||
/* VerifySequenceComplete flushes its verify sequence on success. */
|
||||
cmdSz = BuildCmdHeader(gCmd, TPM_ST_NO_SESSIONS, 0, TPM_CC_GetCapability);
|
||||
PutU32BE(gCmd + cmdSz, TPM_CAP_COMMANDS); cmdSz += 4;
|
||||
PutU32BE(gCmd + cmdSz, TPM_CC_VerifySequenceComplete); cmdSz += 4;
|
||||
PutU32BE(gCmd + cmdSz, 1); cmdSz += 4;
|
||||
PutU32BE(gCmd + 2, (UINT32)cmdSz);
|
||||
|
||||
rspSize = 0;
|
||||
rc = FWTPM_ProcessCommand(&ctx, gCmd, cmdSz, gRsp, &rspSize, 0);
|
||||
AssertIntEQ(rc, TPM_RC_SUCCESS);
|
||||
AssertIntEQ(GetRspRC(gRsp), TPM_RC_SUCCESS);
|
||||
tpma = GetU32BE(gRsp + TPM2_HEADER_SIZE + 9);
|
||||
AssertIntEQ(TpmaCcToCmdCode(tpma), (UINT32)TPM_CC_VerifySequenceComplete);
|
||||
AssertIntEQ(TpmaCcFlushed(tpma), 1);
|
||||
#endif /* WOLFTPM_MLDSA_VERIFY */
|
||||
|
||||
FWTPM_Cleanup(&ctx);
|
||||
fwtpm_pass("GetCapability(COMMANDS) flushed bit:", 0);
|
||||
}
|
||||
#endif /* !FWTPM_NO_HASH_CMDS */
|
||||
|
||||
/* Command codes with reserved bits set must be rejected with
|
||||
* TPM_RC_COMMAND_CODE, never aliased onto a permitted command. */
|
||||
static void test_fwtpm_cc_reserved_bits(void)
|
||||
|
|
@ -12021,6 +12130,9 @@ int fwtpm_unit_tests(int argc, char *argv[])
|
|||
test_fwtpm_getcap_algorithms();
|
||||
test_fwtpm_getcap_commands();
|
||||
test_fwtpm_getcap_commands_tpma();
|
||||
#ifndef FWTPM_NO_HASH_CMDS
|
||||
test_fwtpm_getcap_commands_flushed();
|
||||
#endif
|
||||
test_fwtpm_getcap_properties();
|
||||
test_fwtpm_getcap_pcrs();
|
||||
test_fwtpm_getcap_paging();
|
||||
|
|
|
|||
Loading…
Reference in New Issue