'SPI Hardware Protocol of Trusted Platform Modules (looking for minimal working example)

I am making my first steps in communication with an Infineon OPTIGA TPM SLM 9670 TPM 2.0 via its SPI interface.

I got some first help here, but struggling again.

For starters, I would like to read out the TPM's status register, whose address is given as 0018h.

Interpreting the table from the TPM's SPI Hardware Protocol specification (see below), I do an SPI write of the following four bytes:

0x83            // msb to 1 because I want to read, lower bits to 3 because my xfer consists of 4 bytes
0x00 0x00 0x18  // three register address bytes, naming the register address

When I do an SPI read of 4 bytes (size of the status register) afterwards, I always get FFFFFFFF.

Is this expected or am I doing something wrong?

enter image description here

Table 46 - SPI Bit Protocol



Solution 1:[1]

SPI Hardware Protocol specification:

The TPM SHALL decode transactions sent to offset 0xD4_xxxx when its CS# is asserted

Basically, you must not forget to offset your address by 0xD4:

0x83            // msb to 1 because I want to read, lower bits to 3 because my xfer consists of 4 bytes
0xD4 0x00 0x18  // three register address bytes, naming the register address

Example Sequence

Tpm2_GetRandom

Note: this assumes that the Linux Kernel initialized the TPM, including having sent the Tpm2_Startup command. If you use mainline linux, you do not need to worry about that.

Legend:

  • 04 -> 81: Read register 0x04, read value is 0x81
  • 04 <- 02: Write value 0x02 to register 0x04

For a GetRandom, I have the following sequence. Take that with a grain of salt, that is just my guess when reading the kernel driver. The question marks could be checking that the valid bit in the STS register is set (which is probably also checked whenever STS is read).

Operation My guess of why that is
04 -> 81 Access: check activeLocality, valid, requestUse set, probably if locality is used already
04 <- 02 Access: set requestUse
04 -> A1 Access: check requestUse is set
18 -> 44 ?
18 -> 44 Status: check commandReady is set
18 -> 44D00700 Status: read burst count
24 <- 80010000000C0000017B00 Command Blob except last byte
18 -> 8C Status: check expect is set
24 <- 10 Command Blob last byte
18 -> 84 Status: check expect bit is clear
18 <- 20 Status: set go bit
18 -> 94 ?
18 -> 94 Status: wait for dataAvail
18 -> 941C0000 Status: read burst count
24 -> 80010000001C00000000 Response Blob Header
18 -> 94 Status: wait for dataAvail
18 -> 94120000 Status: read burst count
24 -> 0010755F8A5B158E44F5CD2EDF784156EED7 Response Blob Handles (here none) and Parameters
18 -> 84 Status: wait until valid bit set
18 -> 84 Status: check dataAvail is clear
18 <- 40 Status: set commandReady to reset state machine
04 <- 20 Access: relinquish control

If you're interested, see roughly this part of the driver.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1