tpminfineontpm-2.0

TPM issue: error in session attributes of NV_define when trying to connect PCR policy


So I'm trying to protect an nv-index with a PCR policy. So far reading/writing unprotected NV indexes with attributes TPMA_NV_PLATFORMCREATE|TPMA_NV_OWNERWRITE|TPMA_NV_OWNERREAD|TPMA_NV_PPWRITE|TPMA_NV_PPREAD; works perfectly fine, but assigning a policy doesn't work.

My TPM is connected to an SPI bus on an embedded system. I have no OS, so no TPM_TSS, no TCG_UEFI no linux driver, nothing. just pure SPI.

So here's what I do:

The bytestream is as follows:

Header:
80 01       |   TPM_ST_NO_SESSIONS
00 00 00 3b |   Size (59 bytes)
00 00 01 76 |   TPM_CC_StartAuthSession

Handles:
40 00 00 07 |   TPM2_RH_NULL
40 00 00 07 |   TPM2_RH_NULL

Nonce:
00 20       |   nonce size (32 bytes)
02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 
00 00       |   salt size (0)
03          |   session type: TPM_SE_TRIAL as defined in TPM spec revision 01.59 part 2 page 47 TPM_SE_TRIAL is used to build a policy, whilst TPM_SE_POLICY is used to authenticate with one.
00 10       |   TPM2_ALG_NULL
00 0b       |   TPM2_ALG_SHA256

Response is:

80 01       |   TPM_ST_NO_SESSIONS
00 00 00 30 |   Size (48 bytes)
00 00 00 00 |   Response code (no error)
03 00 00 00 |   session handle
00 20       |   Initial Nonce size (32 bytes) followed by the nonce.
69 72 77 0b ca 29 a7 b8 03 33 71 fa e7 0f 57 9c 09 cd 27 9e ca 43 b9 92 e5 ed 07 8b 98 1d 19 e8

Next I create a PCR policy within this session: (TPM spec, revision 01.59 part 3 page 230)

80 01       |   TPM_ST_NO_SESSIONS
00 00 00 3a |   Length (58 bytes)
00 00 01 7f |   TPM_CC_PolicyPCR
03 00 00 00 |   The session handle we previously obtained
00 20       |   TPM_SHA256_DIGEST_SIZE (32 bytes)
3b 7c 26 4a 0d 84 cc 84 f3 54 cf ce c0 d2 da 9a 88 ee 0c 26 7f 73 28 84 9a 60 2a 62 24 f9 60 49 -> the contents of PCR 7 a.k. the expected value of the PCR
00 00 00 01 |   Number of PCR selections
00 0b       |   TPM2_ALG_SHA256
03          |   Array size of selection (3 bytes)
80 00 00    |   PCR number 7 (7th bit is set counted from 0)

Response is:

80 01       |   TPM_ST_NO_SESSIONS
00 00 00 0a |   Length (10 bytes)
00 00 00 00 |   Response code (no error)

So far so good, but now is where stuff goes haywire.

I now try to define an NV space, which can only be read and written if PCR 7 is in this exact value. The command is defined in TPM spec, revision 01.59 part 3 page 362

80 02       |   TPM_ST_SESSIONS 
00 00 00 4d |   Length (77 bytes)
00 00 01 2a |   TPM_CC_NV_DefineSpace
40 00 00 0c |   TPM2_RH_PLATFORM -> needs TPMA_NV_PLATFORMCREATE attribute!

Auth area is inserted here (thick line in table -> see TPM spec, revision 01.59 part 1 page 97)

00 00 00 09 |   size of auth area (9)
03 00 00 00 |   session handle (previously obtained with start_auth_session)
00          |   session attributes (described in TPM spec, revision 01.59 part 1 page 93)
00 00       |   HMAC size

(End auth area)

00 00       |   auth size (we don't authorize with a password)
00 00 00 2e |   size of TPM2B_NV_PUBLIC
01 50 00 02 |   nv space index (0x1500002) 
00 0b       |   TPM2_ALG_SHA256
40 08 00 08 |   nv attributes:TPMA_NV_PLATFORMCREATE | TPMA_NV_POLICYWRITE | TPMA_NV_POLICYREAD

00 20       |   policy size
3b 7c 26 4a 0d 84 cc 84 f3 54 cf ce c0 d2 da 9a 88 ee 0c 26 7f 73 28 84 9a 60 2a 62 24 f9 60 49 -> the contents of PCR 7 a.k. the expected value of the PCR
00 20       |   nv space size (32 bytes for SHA256)

however now the response is as follows:

80 01       |   TPM_ST_NO_SESSIONS
00 00 00 0a |   Length (10 bytes)
00 00 09 82 |   error 0x982 / 2434

Using the TPM return code decoder from the microsoft store (yes it's pretty helpful) reveals that this is TPM_RC_ATTRIBUTES (inconsistent attributes) on session 0x1

It is true that my session attributes are 0. but when taking a look at TPM spec, revision 01.59 part 1 page 93 I don't see which bits I should set. setting it to 1 (continue session) doesn't change anything. nor dos it look like I need a decrypt,or encrypt session.


Solution

  • You must not supply the session in the TPM2_NV_DefineSpace command. A trial session can/should only be used to generate a session digest which than can be used in object creation.

    Therefor you need to call TPM2_PolicyGetDigest first to get the policy digest and use this digest in the field authPolicy when calling TPM2_NV_DefineSpace.