spitpm

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

  • 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:

    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.