Skip to content

fix(attr_util): correct NV nt field decoding and show it as a friendly name - #3600

Open
katexochen wants to merge 2 commits into
tpm2-software:masterfrom
katexochen:attr-fix-nt
Open

fix(attr_util): correct NV nt field decoding and show it as a friendly name#3600
katexochen wants to merge 2 commits into
tpm2-software:masterfrom
katexochen:attr-fix-nt

Conversation

@katexochen

Copy link
Copy Markdown

Fixes #1797, decided against implementing #1798.

fix(attr_util): decode NV nt field relative to its base

tpm2_attr_util_nv_attrtostr renders the 4-bit TPM_NT field (TPMA_NV
bits 7:4) by walking to the lowest set bit and shifting the value by
that bit index instead of by the field base (bit 4). So any nt value
whose low bit is clear was mis-rendered: bits (0x2) and extend (0x4)
both printed as "nt=0x1", and pinfail (0x8) landed on the width-1
slot and printed a bare "nt" with no value. Only values with bit 4
set (counter 0x1, pinpass 0x9, ...) came out right, which is why the
existing tests never caught it.

Anchor extraction on the field base (bit_index & ~(w - 1)) and give
all four nt table slots the full field width (4), so the whole nibble
is read as (attrs >> 4) & 0xF regardless of which bit the scanner
lands on. The same expression reduces to bit_index for single-bit
attributes (w == 1), so their behavior is unchanged.

feat(attr_util): render NV nt field as a friendly name

The attribute parser already accepts friendly TPM_NT names
(nt=extend, nt=counter, ...), but tpm2_attr_util_nv_attrtostr only
ever emitted the raw field value (nt=0x4), so tpm2_nvreadpublic's
"friendly" output wasn't symmetric with the input it accepts.

Map the decoded nt field value back to its name, falling back to hex for
any value that isn't a defined type. Only the human-readable "friendly:"
string changes (e.g. nt=0x9 -> nt=pinpass); the raw "value:" field is
unchanged.

Keep the nt= prefix so the string still round-trips through
tpm2_nvdefine -a, which parses this same format.

tpm2_attr_util_nv_attrtostr renders the 4-bit TPM_NT field (TPMA_NV
bits 7:4) by walking to the lowest set bit and shifting the value by
that bit index instead of by the field base (bit 4). So any nt value
whose low bit is clear was mis-rendered: bits (0x2) and extend (0x4)
both printed as "nt=0x1", and pinfail (0x8) landed on the width-1
slot and printed a bare "nt" with no value. Only values with bit 4
set (counter 0x1, pinpass 0x9, ...) came out right, which is why the
existing tests never caught it.

Anchor extraction on the field base (bit_index & ~(w - 1)) and give
all four nt table slots the full field width (4), so the whole nibble
is read as (attrs >> 4) & 0xF regardless of which bit the scanner
lands on. The same expression reduces to bit_index for single-bit
attributes (w == 1), so their behavior is unchanged.

Signed-off-by: Paul Meyer <katexochen0@gmail.com>
The attribute parser already accepts friendly TPM_NT names
(nt=extend, nt=counter, ...), but tpm2_attr_util_nv_attrtostr only
ever emitted the raw field value (nt=0x4), so tpm2_nvreadpublic's
"friendly" output wasn't symmetric with the input it accepts.

Map the decoded nt field value back to its name, falling back to hex for
any value that isn't a defined type. Only the human-readable "friendly:"
string changes (e.g. nt=0x9 -> nt=pinpass); the raw "value:" field is
unchanged.

Keep the nt= prefix so the string still round-trips through
tpm2_nvdefine -a, which parses this same format.

Signed-off-by: Paul Meyer <katexochen0@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

nt decoding scheme broken

1 participant