Skip to content

# Bug: stse_perso_info_t AC status 2-bit mask truncates valid AC values #69

@Grolleau-Benjamin

Description

@Grolleau-Benjamin

The cmd_AC_status and ext_cmd_AC_status fields are packed structures where each command occupies a 2-bit slot. This 2-bit assumption is inconsistent with the stse_cmd_access_conditions_t enum which defines 6 values, requiring at least 3 bits.

This affects initialization, write, and read operations consistently across both cmd and ext_cmd variants.

The 2-bit mask 0x03 is used throughout:

Initialization — all slots default to 0b01 (STSE_CMD_AC_FREE), but any value ≥ 4 could never be represented anyway:

pSTSE->perso_info.cmd_AC_status     = 0x5555555555555555;
pSTSE->perso_info.ext_cmd_AC_status = 0x5555555555555555;

Write — STSE_CMD_AC_ADMIN_OR_PWD (4) and STSE_CMD_AC_ADMIN_OR_HOST (5) are silently truncated:

pPerso->cmd_AC_status &= ~((PLAT_UI64)0x03 << offset);
pPerso->cmd_AC_status |=  (PLAT_UI64)protection << offset;

Read — the getter masks the result to 2 bits, so values 4 and 5 can never be read back:

return (pPerso->cmd_AC_status >> offset) & 0x03;

The same three issues apply identically to ext_cmd_AC_status.

typedef enum stse_cmd_access_conditions_t {
    STSE_CMD_AC_NEVER         = 0,
    STSE_CMD_AC_FREE          = 1,
    STSE_CMD_AC_ADMIN         = 2,
    STSE_CMD_AC_HOST          = 3,
    STSE_CMD_AC_ADMIN_OR_PWD  = 4,  // ← truncated to NEVER (0)
    STSE_CMD_AC_ADMIN_OR_HOST = 5   // ← truncated to FREE  (1)
} stse_cmd_access_conditions_t;

Setting or reading STSE_CMD_AC_ADMIN_OR_PWD or STSE_CMD_AC_ADMIN_OR_HOST produces silent security misconfigurations with no error.

Proposed fix

Widen the mask and slot size from 2 bits to 3 bits (0x07) across initialization, setter, and getter — for both cmd and ext_cmdvariants. However, the offset, currently computed as cmd_code * 2, would need to become cmd_code * 3.

This makes packing into a PLAT_UI64 no longer viable: at 3 bits per slot, a PLAT_UI64 is limited to 21 commands, which is insufficient for the current 29 commands.

The only correct solution is to switch to a PLAT_UI8 array:

PLAT_UI8 cmd_AC_status[STSE_CMD_COUNT];
PLAT_UI8 ext_cmd_AC_status[STSE_EXT_CMD_COUNT];

This comes at a memory cost of 29 * 2 - 8 * 2 = 42 additional bytes compared to the current two PLAT_UI64 fields.

Metadata

Metadata

Assignees

Labels

bugSomething isn't working

Type

No fields configured for Bug.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions