Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Attributes of TPM NV counters (and bits) cannot be represented as string #318

Open
niooss-ledger opened this issue Jan 13, 2022 · 1 comment

Comments

@niooss-ledger
Copy link
Contributor

Hello,

While testing #317 on a real TPM, I encountered an exception because I use a NV index with a counter. This issue can be reproduced without a TPM by the following Python script:

from tpm2_pytss import *
nvPublic=TPMS_NV_PUBLIC(
    nvIndex=0x1000000,
    nameAlg=TPM2_ALG.SHA256,
    attributes=TPMA_NV.OWNERWRITE
    | TPMA_NV.OWNERREAD
    | TPMA_NV.AUTHREAD
    | TPMA_NV.AUTHWRITE
    | (TPM2_NT.COUNTER << TPMA_NV.TPM2_NT_SHIFT),
    authPolicy=b"",
    dataSize=8,
)
print(str(nvPublic.attributes))

With tpm2-pytss 1.0.0-rc1, this outputs:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File ".../tpm2_pytss/constants.py", line 283, in __str__
    raise ValueError(f"unnmatched values left: 0x{cv:x}")
ValueError: unnmatched values left: 0x10

This exception occurs because TPM2_NT.COUNTER << TPMA_NV.TPM2_NT_SHIFT is not defined in TPMA_NV. To fix it, maybe TPMA_NV could override __str__() to report the value of the four TPM2_NT bits.

For information with tpm2-tools, tpm2_nvreadpublic displays this value as ownerwrite|authwrite|nt=0x1|writeall|ownerread|authread|written. It would be nice if there was a way to report nt=1, nt=counter or counter in the result of str(nvPublic.attributes).

By the way, I also found two other issues related to this:

  • TPMA_NV.to_string(0x60006) does not work (it raises ValueError: Could not match 393222 to class TPMA_NV). Users have to use str(TPMA_NV(0x60006)) to get a friendly representation. This feels strange.
  • The value 4 is defined twice in TPMA_NV: TPMA_NV.TPM2_NT_SHIFT = 4 and TPMA_NV.AUTHWRITE = 4. It would be strange to have TPM2_NT_SHIFT reported in the friendly representation of a NV attribute and the code seems to be fragile to ensure that AUTHWRITE is always preferred to TPM2_NT_SHIFT when using for example str(TPMA_NV(4)): it relies of the order given by vars(TPMA_NV).items().
@whooo whooo mentioned this issue Jan 13, 2022
@williamcroberts
Copy link
Member

TPMA_NV.to_string(0x60006) does not work (it raises ValueError: Could not match 393222 to class TPMA_NV). Users have to use str(TPMA_NV(0x60006)) to get a friendly representation. This feels strange

So to_string is for mapping something like a constant in a class, which is why it's a class method versus an instance method. So in TPMA_NV class something like TPMA_NV.to_string(0x20000) will return the full constant name of TPMA_NV.OWNERREAD. Where the instance method for __str__ will return the lowercase, normalized, friendly values.

str(TPMA_NV.OWNERREAD|TPMA_NV.OWNERWRITE)
'ownerwrite|ownerread'

So to make the classmethod to_string try and figure out if they want the class constant or the friendly name, would be tricky, ie would TPMA_NV.to_string(0x20000) return TPMA_NV.OWENERREAD or ownerread

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

No branches or pull requests

2 participants