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

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions