tpm2: Base enabledCommands on command index rather than command code

Base the enabledCommands array on the command index rather than the command
code since the latter left the first few bytes always unused since command
codes start at 0x11f only.

After this change, ppList, auditCommands, and enabledCommandsByIdx bitmaps
are all based on command indices.

Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
This commit is contained in:
Stefan Berger 2026-03-09 12:26:13 -04:00
parent bc4d5e8de8
commit dc665f95cc
2 changed files with 36 additions and 26 deletions

View File

@ -15,6 +15,9 @@
#define CMD_SEPARATOR_STR ","
/* the following assert must never change */
MUST_BE(TPM_CC_FIRST == TPM_CC_NV_UndefineSpaceSpecial);
/* List of supported commands sorted by command codes.
* Commands can be disabled that are optional or recommended in automotive
* thin profile.
@ -169,14 +172,15 @@ RuntimeCommandsEnableAllCommands(struct RuntimeCommands *RuntimeCommands,
assert(maxStateFormatLevel >= 1);
MemorySet(RuntimeCommands->enabledCommands, 0 , sizeof(RuntimeCommands->enabledCommands));
MemorySet(RuntimeCommands->enabledCommandsByIdx, 0 ,
sizeof(RuntimeCommands->enabledCommandsByIdx));
for (commandIndex = 0; commandIndex < ARRAY_SIZE(s_CommandProperties); commandIndex++) {
/* skip over unsupported commands or those exceeding the max. stateFormatLevel */
if (!s_CommandProperties[commandIndex].name ||
s_CommandProperties[commandIndex].stateFormatLevel > maxStateFormatLevel)
continue;
SET_BIT(IdxToCc(commandIndex), RuntimeCommands->enabledCommands);
SET_BIT(commandIndex, RuntimeCommands->enabledCommandsByIdx);
}
}
@ -273,7 +277,8 @@ RuntimeCommandsSetProfile(struct RuntimeCommands *RuntimeCommands,
return TPM_RC_SUCCESS;
}
MemorySet(&RuntimeCommands->enabledCommands, 0, sizeof(RuntimeCommands->enabledCommands));
MemorySet(&RuntimeCommands->enabledCommandsByIdx, 0,
sizeof(RuntimeCommands->enabledCommandsByIdx));
token = *newProfile;
while (1) {
@ -316,7 +321,7 @@ RuntimeCommandsSetProfile(struct RuntimeCommands *RuntimeCommands,
filtered = true;
continue;
}
SET_BIT(IdxToCc(commandIndex), RuntimeCommands->enabledCommands);
SET_BIT(commandIndex, RuntimeCommands->enabledCommandsByIdx);
assert(s_CommandProperties[commandIndex].stateFormatLevel > 0);
*stateFormatLevel = MAX(*stateFormatLevel,
s_CommandProperties[commandIndex].stateFormatLevel);
@ -332,7 +337,7 @@ RuntimeCommandsSetProfile(struct RuntimeCommands *RuntimeCommands,
if (!s_CommandProperties[commandIndex].name)
continue;
if (!s_CommandProperties[commandIndex].canBeDisabled &&
!TEST_BIT(IdxToCc(commandIndex), RuntimeCommands->enabledCommands)) {
!TEST_BIT(commandIndex, RuntimeCommands->enabledCommandsByIdx)) {
TPMLIB_LogTPM2Error("Command %s (0x%x) must be enabled.\n",
s_CommandProperties[commandIndex].name, IdxToCc(commandIndex));
goto exit;
@ -386,39 +391,44 @@ RuntimeCommandsSwitchProfile(struct RuntimeCommands *RuntimeCommands,
return retVal;
}
/* Check whether the given command is runtime-disabled */
LIB_EXPORT BOOL
RuntimeCommandsCheckEnabled(struct RuntimeCommands *RuntimeCommands,
TPM_CC commandCode // IN: the commandCode to check
)
/* Check whether the given command is runtime-enabled given it's index */
static BOOL
RuntimeCommandsCheckEnabledByIdx(struct RuntimeCommands *RuntimeCommands,
COMMAND_INDEX commandIndex // IN: the index of the Command to Check
)
{
if (CcToIdx(commandCode) >= ARRAY_SIZE(s_CommandProperties)) {
if (commandIndex >= ARRAY_SIZE(s_CommandProperties)) {
TPMLIB_LogPrintf("IsEnabled(0x%x): out-of-range command code\n",
commandCode);
IdxToCc(commandIndex));
return FALSE;
}
TPMLIB_LogPrintf("IsEnEnabled(0x%x = '%s'): %d\n",
commandCode,
s_CommandProperties[CcToIdx(commandCode)].name,
TEST_BIT(commandCode, RuntimeCommands->enabledCommands));
if (!TEST_BIT(commandCode, RuntimeCommands->enabledCommands))
IdxToCc(commandIndex),
s_CommandProperties[commandIndex].name,
TEST_BIT(commandIndex, RuntimeCommands->enabledCommandsByIdx));
if (!TEST_BIT(commandIndex, RuntimeCommands->enabledCommandsByIdx))
return FALSE;
return TRUE;
}
LIB_EXPORT BOOL
RuntimeCommandsCheckEnabled(struct RuntimeCommands *RuntimeCommands,
TPM_CC cc)
{
return RuntimeCommandsCheckEnabledByIdx(RuntimeCommands, CcToIdx(cc));
}
/* Get the number of enabled commands. */
LIB_EXPORT UINT32
RuntimeCommandsCountEnabled(struct RuntimeCommands *RuntimeCommands)
{
TPM_CC commandCode;
COMMAND_INDEX commandIndex;
UINT32 count = 0;
/* the following assert must never change */
MUST_BE(TPM_CC_FIRST == TPM_CC_NV_UndefineSpaceSpecial);
for (commandCode = TPM_CC_FIRST;
commandCode < sizeof(RuntimeCommands->enabledCommands) * 8;
commandCode++) {
if (TEST_BIT(commandCode, RuntimeCommands->enabledCommands))
for (commandIndex = 0;
commandIndex < sizeof(RuntimeCommands->enabledCommandsByIdx) * 8;
commandIndex++) {
if (TEST_BIT(commandIndex, RuntimeCommands->enabledCommandsByIdx))
count++;
}
return count;
@ -486,11 +496,11 @@ RuntimeCommandsPrint(struct RuntimeCommands *RuntimeCommands,
break;
case RUNTIME_CMD_ENABLED:
// skip over disabled ones
doPrint = RuntimeCommandsCheckEnabled(RuntimeCommands, IdxToCc(commandIndex));
doPrint = RuntimeCommandsCheckEnabledByIdx(RuntimeCommands, commandIndex);
break;
case RUNTIME_CMD_DISABLED:
// skip over enabled ones
doPrint = !RuntimeCommandsCheckEnabled(RuntimeCommands, IdxToCc(commandIndex));
doPrint = !RuntimeCommandsCheckEnabledByIdx(RuntimeCommands, commandIndex);
break;
default:
continue;

View File

@ -15,7 +15,7 @@
#define NUM_ENTRIES_COMMAND_PROPERTIES (CcToIdx(TPM_CC_LAST) + 1)
struct RuntimeCommands {
unsigned char enabledCommands[(IdxToCc(NUM_ENTRIES_COMMAND_PROPERTIES) + 7) / 8];
unsigned char enabledCommandsByIdx[BITS_TO_BYTES(TPM_CC_LAST - TPM_CC_FIRST + 1)];
char *commandsProfile;
};