Topic: WolfTPM_SPI_Genode_integration

Dear,

I am currently working on a wolfTPM port to the Genode Operating System Framework. I have set up a scenario that connect to a TPM using the GPIO driver and the SPI driver, then it executes the wolfTPM unit test. Furthermore, I am able to communicate with the TPM but not to initialize it successfully. The unit-test logs some error, but I stumble understanding it and figuring out what the error from the StartUp command is.

Here is the log:

[spi_driver] [send] buffer(12): 80 01 00 00 00 0C 00 00 01 44 00 00 
[spi_driver] [received] buffer(12): 00 00 00 01 81 40 00 00 01 3F FF FF 

[test-wolftpm] TPM2: Caps 0x00000000, Did 0x0000, Vid 0x0000, Rid 0x 0
[test-wolftpm] TPM2: Caps 0x00000000, Did 0x0000, Vid 0x0000, Rid 0x 0

[spi_driver] [send] buffer(12): 80 01 00 00 00 0c 00 00 01 45 00 00
[spi_driver] [received] buffer(12): 80 00 00 00 00 0c 00 00 01 45 00 00

[test-wolftpm] TPM2_Shutdown failed 325: TPM_RC_AUTH_CONTEXT: Use of an authorization session with a context command or another command that cannot have an authorization session
[test-wolftpm] Test TPM Wrapper:        Init:   Passed
[test-wolftpm] TPM2: Caps 0x00000000, Did 0x0000, Vid 0x0000, Rid 0x 0

[spi_driver] [send] buffer(22): 80 01 00 00 00 16 00 00 01 7a 00 00 00 06 00 00 01 05 00 00 00 08
[spi_driver] [received] buffer(22): 80 00 00 00 00 16 00 00 01 7a 00 00 00 06 00 00 01 05 00 00 00 08

[test-wolftpm] TPM2_GetCapability failed 0x17a: Unknown

(expected crash due to the test-wolftpm failure)

I am using the microkernel that come with Genode. The TPM currently in use is the Infineon SLB9670. I had to write the SPI driver that target imx8q (aarch64) based board because none exist before. My guesses are that some initialization steps are missing/wrong or something is broken on the SPI driver side, but I can't point it out.

----

On the first transaction, rx received:

00 00 00 01 81 40 00 00 01 3F FF FF

We can observe that the number of byte received seems to correspond to a valid number of bytes for a response header, 10. But the bytes values seems garbage. Shall I expect the TPM not being initialized, and then I shall ignore this first received transaction?

Then, if the Shutdown command failed, is there more steps that I should be aware of to initialize the TPM before running the unit tests?

----

On existing implementation did you had to set up a specific wait_state for the SPI controller?

On the first place I used to send the command data all in one burst and I only get garbage in return. Since I change it to be sent byte by byte, and it seems to be better. This seems obviously wrong. I tried to have a look at the linux_5.12 SPI's driver source, but I couldn't make any guesses.


Thanks for reading my post!

Best,
JA

Share

Re: WolfTPM_SPI_Genode_integration

Hi JA,

The Infineon SLB9670 does not require SPI wait states. In fact it is the only TPM module that doesn't require the SPI wait states.

Some things to try:
1) Lowering or increasing the SPI bus speed.
2) Give additional time for the SPI CS and first clock
3) Make sure your SPI mode is 0 (CPOL=0, CPHA=0).

For reference: To use a SPI wait state:
1) Assert chip select (low)
2) Send 4 byte header
3) Read a single byte and checks for the MSB (0x80) is set (read single byte until set) Typically 1-2 times.
4) Read remainder
5) De-assert chip select (high)

Here is a simple get capabilities for an Infineon SLB9670 on my Raspberry Pi:

PI4:pi@raspberrypi:~/wolftpm $ ./examples/wrap/wrap_test
TPM2 Demo for Wrapper API's
Found TPM @ /dev/spidev0.0
TPM2_IoCb: Ret 0, Sz 5
    80 d4 00 00 00                                  | .....
    00 00 00 01 a1                                  | .....
TPM2_IoCb: Ret 0, Sz 5
    80 d4 00 00 00                                  | .....
    40 00 00 01 a1                                  | @....
TPM2_IoCb: Ret 0, Sz 8
    83 d4 00 14 00 00 00 00                         | ........
    40 00 00 01 97 06 00 30                         | @......0
TPM2_IoCb: Ret 0, Sz 8
    83 d4 0f 00 00 00 00 00                         | ........
    00 00 00 01 d1 15 1b 00                         | ........
TPM2_IoCb: Ret 0, Sz 5
    80 d4 0f 04 00                                  | .....
    00 00 00 01 16                                  | .....
TPM2: Caps 0x30000697, Did 0x001b, Vid 0x15d1, Rid 0x16
Command: 12
    80 01 00 00 00 0c 00 00 01 44 00 00             | .........D..
TPM2_IoCb: Ret 0, Sz 5
    80 d4 00 18 00                                  | .....
    40 00 00 01 44                                  | @...D
TPM2_IoCb: Ret 0, Sz 6
    81 d4 00 19 00 00                               | ......
    40 00 00 01 ff 00                               | @.....
TPM2_IoCb: Ret 0, Sz 16
    0b d4 00 24 80 01 00 00 00 0c 00 00 01 44 00 00 | ...$.........D..
    00 00 00 01 00 00 00 00 00 00 00 00 00 00 00 00 | ................
TPM2_IoCb: Ret 0, Sz 5
    80 d4 00 18 00                                  | .....
    00 00 00 01 0c                                  | .....
TPM2_IoCb: Ret 0, Sz 5
    80 d4 00 18 00                                  | .....
    40 00 00 01 84                                  | @....
TPM2_IoCb: Ret 0, Sz 5
    00 d4 00 18 20                                  | ....
    40 00 00 01 00                                  | @....
TPM2_IoCb: Ret 0, Sz 5
    80 d4 00 18 00                                  | .....
    00 00 00 01 84                                  | .....
TPM2_IoCb: Ret 0, Sz 5
    80 d4 00 18 00                                  | .....
    40 00 00 01 94                                  | @....
TPM2_IoCb: Ret 0, Sz 6
    81 d4 00 19 00 00                               | ......
    00 00 00 01 0a 00                               | ......
TPM2_IoCb: Ret 0, Sz 14
    89 d4 00 24 00 00 00 00 00 00 00 00 00 00       | ...$..........
    00 00 00 01 80 01 00 00 00 0a 00 00 01 00       | ..............
Response: 10
    80 01 00 00 00 0a 00 00 01 00                   | ..........
TPM2_IoCb: Ret 0, Sz 5
    00 d4 00 18 40                                  | ....@
    00 00 00 01 00                                  | .....
TPM2_Startup pass
Command: 11
    80 01 00 00 00 0b 00 00 01 43 01                | .........C.
TPM2_IoCb: Ret 0, Sz 5
    80 d4 00 18 00                                  | .....
    00 00 00 01 44                                  | ....D
TPM2_IoCb: Ret 0, Sz 6
    81 d4 00 19 00 00                               | ......
    40 00 00 01 ff 00                               | @.....
TPM2_IoCb: Ret 0, Sz 15
    0a d4 00 24 80 01 00 00 00 0b 00 00 01 43 01    | ...$.........C.
    00 00 00 01 00 00 00 00 00 00 00 00 00 00 00    | ...............
TPM2_IoCb: Ret 0, Sz 5
    80 d4 00 18 00                                  | .....
    00 00 00 01 0c                                  | .....
TPM2_IoCb: Ret 0, Sz 5
    80 d4 00 18 00                                  | .....
    40 00 00 01 84                                  | @....
TPM2_IoCb: Ret 0, Sz 5
    00 d4 00 18 20                                  | ....
    40 00 00 01 00                                  | @....
TPM2_IoCb: Ret 0, Sz 5
    80 d4 00 18 00                                  | .....
    00 00 00 01 84                                  | .....
TPM2_IoCb: Ret 0, Sz 5
    80 d4 00 18 00                                  | .....
    40 00 00 01 84                                  | @....
TPM2_IoCb: Ret 0, Sz 5
    80 d4 00 18 00                                  | .....
    40 00 00 01 84                                  | @....
TPM2_IoCb: Ret 0, Sz 5
    80 d4 00 18 00                                  | .....
    40 00 00 01 84                                  | @....
TPM2_IoCb: Ret 0, Sz 5
    80 d4 00 18 00                                  | .....
    40 00 00 01 80                                  | @....

...

TPM2_IoCb: Ret 0, Sz 5
    80 d4 00 18 00                                  | .....
    40 00 00 01 80                                  | @....
TPM2_IoCb: Ret 0, Sz 5
    80 d4 00 18 00                                  | .....
    40 00 00 01 84                                  | @....
TPM2_IoCb: Ret 0, Sz 5
    80 d4 00 18 00                                  | .....
    40 00 00 01 94                                  | @....
TPM2_IoCb: Ret 0, Sz 6
    81 d4 00 19 00 00                               | ......
    00 00 00 01 0a 00                               | ......
TPM2_IoCb: Ret 0, Sz 14
    89 d4 00 24 00 00 00 00 00 00 00 00 00 00       | ...$..........
    00 00 00 01 80 01 00 00 00 0a 00 00 00 00       | ..............
Response: 10
    80 01 00 00 00 0a 00 00 00 00                   | ..........
TPM2_IoCb: Ret 0, Sz 5
    00 d4 00 18 40                                  | ....@
    00 00 00 01 00                                  | .....
TPM2_SelfTest pass
Command: 22
    80 01 00 00 00 16 00 00 01 7a 00 00 00 06 00 00 | .........z......
    01 05 00 00 00 08                               | ......
TPM2_IoCb: Ret 0, Sz 5
    80 d4 00 18 00                                  | .....
    00 00 00 01 44                                  | ....D
TPM2_IoCb: Ret 0, Sz 6
    81 d4 00 19 00 00                               | ......
    40 00 00 01 ff 00                               | @.....
TPM2_IoCb: Ret 0, Sz 26
    15 d4 00 24 80 01 00 00 00 16 00 00 01 7a 00 00 | ...$.........z..
    00 06 00 00 01 05 00 00 00 08                   | ..........
    00 00 00 01 00 00 00 00 00 00 00 00 00 00 00 00 | ................
    00 00 00 00 00 00 00 00 00 00                   | ..........
TPM2_IoCb: Ret 0, Sz 5
    80 d4 00 18 00                                  | .....
    00 00 00 01 0c                                  | .....
TPM2_IoCb: Ret 0, Sz 5
    80 d4 00 18 00                                  | .....
    40 00 00 01 84                                  | @....
TPM2_IoCb: Ret 0, Sz 5
    00 d4 00 18 20                                  | ....
    40 00 00 01 00                                  | @....
TPM2_IoCb: Ret 0, Sz 5
    80 d4 00 18 00                                  | .....
    00 00 00 01 84                                  | .....
TPM2_IoCb: Ret 0, Sz 5
    80 d4 00 18 00                                  | .....
    40 00 00 01 84                                  | @....
TPM2_IoCb: Ret 0, Sz 5
    80 d4 00 18 00                                  | .....
    40 00 00 01 94                                  | @....
TPM2_IoCb: Ret 0, Sz 6
    81 d4 00 19 00 00                               | ......
    40 00 00 01 53 00                               | @...S.
TPM2_IoCb: Ret 0, Sz 14
    89 d4 00 24 00 00 00 00 00 00 00 00 00 00       | ...$..........
    00 00 00 01 80 01 00 00 00 53 00 00 00 00       | .........S....
TPM2_IoCb: Ret 0, Sz 5
    80 d4 00 18 00                                  | .....
    00 00 00 01 94                                  | .....
TPM2_IoCb: Ret 0, Sz 6
    81 d4 00 19 00 00                               | ......
    40 00 00 01 49 00                               | @...I.
TPM2_IoCb: Ret 0, Sz 68
    bf d4 00 24 00 00 00 00 00 00 00 00 00 00 00 00 | ...$............
    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | ................
    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | ................
    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | ................
    00 00 00 00                                     | ....
    00 00 00 01 01 00 00 00 06 00 00 00 08 00 00 01 | ................
    05 49 46 58 00 00 00 01 06 53 4c 42 39 00 00 01 | .IFX.....SLB9...
    07 36 37 30 00 00 00 01 08 00 00 00 00 00 00 01 | .670............
    09 00 00 00 00 00 00 01 0a 00 00 00 00 00 00 01 | ................
    0b 00 07 00                                     | ....
TPM2_IoCb: Ret 0, Sz 5
    80 d4 00 18 00                                  | .....
    00 00 00 01 94                                  | .....
TPM2_IoCb: Ret 0, Sz 6
    81 d4 00 19 00 00                               | ......
    00 00 00 01 09 00                               | ......
TPM2_IoCb: Ret 0, Sz 13
    88 d4 00 24 00 00 00 00 00 00 00 00 00          | ...$.........
    00 00 00 01 55 00 00 01 0c 00 11 cb 00          | ....U........
Response: 83
    80 01 00 00 00 53 00 00 00 00 01 00 00 00 06 00 | .....S..........
    00 00 08 00 00 01 05 49 46 58 00 00 00 01 06 53 | .......IFX.....S
    4c 42 39 00 00 01 07 36 37 30 00 00 00 01 08 00 | LB9....670......
    00 00 00 00 00 01 09 00 00 00 00 00 00 01 0a 00 | ................
    00 00 00 00 00 01 0b 00 07 00 55 00 00 01 0c 00 | ..........U.....
    11 cb 00                                        | ...
TPM2_IoCb: Ret 0, Sz 5
    00 d4 00 18 40                                  | ....@
    00 00 00 01 00                                  | .....
Command: 22
    80 01 00 00 00 16 00 00 01 7a 00 00 00 06 00 00 | .........z......
    01 2d 00 00 00 01                               | .-....
TPM2_IoCb: Ret 0, Sz 5
    80 d4 00 18 00                                  | .....
    00 00 00 01 44                                  | ....D
TPM2_IoCb: Ret 0, Sz 6
    81 d4 00 19 00 00                               | ......
    40 00 00 01 ff 00                               | @.....
TPM2_IoCb: Ret 0, Sz 26
    15 d4 00 24 80 01 00 00 00 16 00 00 01 7a 00 00 | ...$.........z..
    00 06 00 00 01 2d 00 00 00 01                   | .....-....
    00 00 00 01 00 00 00 00 00 00 00 00 00 00 00 00 | ................
    00 00 00 00 00 00 00 00 00 00                   | ..........
TPM2_IoCb: Ret 0, Sz 5
    80 d4 00 18 00                                  | .....
    00 00 00 01 84                                  | .....
TPM2_IoCb: Ret 0, Sz 5
    00 d4 00 18 20                                  | ....
    40 00 00 01 00                                  | @....
TPM2_IoCb: Ret 0, Sz 5
    80 d4 00 18 00                                  | .....
    00 00 00 01 84                                  | .....
TPM2_IoCb: Ret 0, Sz 5
    80 d4 00 18 00                                  | .....
    40 00 00 01 94                                  | @....
TPM2_IoCb: Ret 0, Sz 6
    81 d4 00 19 00 00                               | ......
    00 00 00 01 1b 00                               | ......
TPM2_IoCb: Ret 0, Sz 14
    89 d4 00 24 00 00 00 00 00 00 00 00 00 00       | ...$..........
    00 00 00 01 80 01 00 00 00 1b 00 00 00 00       | ..............
TPM2_IoCb: Ret 0, Sz 5
    80 d4 00 18 00                                  | .....
    00 00 00 01 94                                  | .....
TPM2_IoCb: Ret 0, Sz 6
    81 d4 00 19 00 00                               | ......
    00 00 00 01 11 00                               | ......
TPM2_IoCb: Ret 0, Sz 21
    90 d4 00 24 00 00 00 00 00 00 00 00 00 00 00 00 | ...$............
    00 00 00 00 00                                  | .....
    00 00 00 01 01 00 00 00 06 00 00 00 01 00 00 01 | ................
    2d 00 00 00 01                                  | -....
Response: 27
    80 01 00 00 00 1b 00 00 00 00 01 00 00 00 06 00 | ................
    00 00 01 00 00 01 2d 00 00 00 01                | ......-....
TPM2_IoCb: Ret 0, Sz 5
    00 d4 00 18 40                                  | ....@
    00 00 00 01 00                                  | .....
Mfg IFX (1), Vendor SLB9670, Fw 7.85 (4555), FIPS 140-2 1, CC-EAL4 1

Thanks,
David Garske, wolfSSL

Share

Re: WolfTPM_SPI_Genode_integration

Dear David,

Thank-you very much for your answer!

After a lot of debugging, an error was found in our wolf TPM port, the response from the TPM is in fact a duplicate of the buffer sent (with small alteration). After fixing it, here is the output of the wolf TPM unit test:

[init -> spi_drv] ECSPI initialized.
[init -> test-wolftpm] tar archive 'examples.tar' local at 0x10c000, size is 450560
[init -> test-wolftpm] Waiting TPM initialization
[init -> test-wolftpm] TPM2: Caps 0x00000000, Did 0x0000, Vid 0x0000, Rid 0x 0
[init -> test-wolftpm] TPM2: Caps 0x00000000, Did 0x0000, Vid 0x0000, Rid 0x 0
[init -> test-wolftpm] [send] buffer(12): 80 01 00 00 00 0c 00 00 01 45 00 00
[init -> imx8q_spi_drv] Begin transaction with 12 bytes.
[init -> imx8q_spi_drv] Session bus settings:
[init -> imx8q_spi_drv]         slave_select: 0
[init -> imx8q_spi_drv]         mode: 0x0
[init -> imx8q_spi_drv]                 clk_polarity: 0x0
[init -> imx8q_spi_drv]                 clk_phase: 0x0
[init -> imx8q_spi_drv]         clock_idle_state: 0x0
[init -> imx8q_spi_drv]         ss_line_active_state: 0x0
[init -> imx8q_spi_drv] Pre-divider: 0xb
[init -> imx8q_spi_drv] Post-divider: 0x0
[init -> imx8q_spi_drv] Burst length: 95
[init -> imx8q_spi_drv] write: 0x80010000
[init -> imx8q_spi_drv] write: 0x000c0000
[init -> imx8q_spi_drv] write: 0x01450000
[init -> imx8q_spi_drv] Rx FIFO is ready.
[init -> imx8q_spi_drv] Tx transaction completed.
[init -> imx8q_spi_drv] read: 0x01000000
[init -> imx8q_spi_drv] read: 0x00004081
[init -> imx8q_spi_drv] read: 0xffff3f01
[init -> test-wolftpm] [received] buffer(12): 00 00 00 01 81 40 00 00 01 3f ff ff
[init -> test-wolftpm] TPM2_Shutdown failed 319: Unknown
[init -> test-wolftpm] Test TPM Wrapper:        Init:   Passed
[init -> test-wolftpm] TPM2: Caps 0x00000000, Did 0x0000, Vid 0x0000, Rid 0x 0
[init -> test-wolftpm] [send] buffer(22): 80 01 00 00 00 16 00 00 01 7a 00 00 00 06 00 00 01 05 00 00 00 08
[init -> imx8q_spi_drv] Begin transaction with 22 bytes.
[init -> imx8q_spi_drv] Session bus settings:
[init -> imx8q_spi_drv]         slave_select: 0
[init -> imx8q_spi_drv]         mode: 0x0
[init -> imx8q_spi_drv]                 clk_polarity: 0x0
[init -> imx8q_spi_drv]                 clk_phase: 0x0
[init -> imx8q_spi_drv]         clock_idle_state: 0x0
[init -> imx8q_spi_drv]         ss_line_active_state: 0x0
[init -> imx8q_spi_drv] Pre-divider: 0xb
[init -> imx8q_spi_drv] Post-divider: 0x0
[init -> imx8q_spi_drv] Burst length: 175
[init -> imx8q_spi_drv] Unaligned write: 0x80010000
[init -> imx8q_spi_drv] write: 0x00000016
[init -> imx8q_spi_drv] write: 0x0000017a
[init -> imx8q_spi_drv] write: 0x00000006
[init -> imx8q_spi_drv] write: 0x00000105
[init -> imx8q_spi_drv] write: 0x00000008
[init -> imx8q_spi_drv] Rx FIFO is ready.
[init -> imx8q_spi_drv] Tx transaction completed.
[init -> imx8q_spi_drv] unaligned read: 0x00000000
[init -> imx8q_spi_drv] read: 0x00000100
[init -> imx8q_spi_drv] read: 0x3f010000
[init -> imx8q_spi_drv] read: 0xffffffff
[init -> imx8q_spi_drv] read: 0xffffffff
[init -> imx8q_spi_drv] read: 0xffffffff
[init -> test-wolftpm] [received] buffer(22): 00 00 00 01 00 00 00 00 01 3f ff ff ff ff ff ff ff ff ff ff ff ff
[init -> test-wolftpm] TPM2_GetCapability failed 0x13f: Unknown
[init -> test-wolftpm] 
[init -> test-wolftpm] ERROR - /XXXX/src/lib/wolftpm/tests/unit_tests.c line 132 failed with:
[init -> test-wolftpm]     expected: rc == 0
[init -> test-wolftpm]     result:   319(0x13f) != 0(0x0)
[init -> test-wolftpm] 
[init -> test-wolftpm] Error: raise(ABRT)
[init] child "test-wolftpm" exited with exit value -1

I have added verbosity to the SPI driver. Please note on this run every word are swapped, the result is the same if not. Also, I don't have a read/write logic for the SPI driver. But only a 'transaction', I give a buffer of X bytes to the driver, it returns me that buffer with the X bytes received from the slave devices during the transaction.

We can now observe that in contrast with my first post, the data we received seems incoherent no matter the command we send. As you suggest, I have double-checked and made a peer-review about those parameters. Unfortunately, I couldn't get an oscilloscope connected to the bus because it is wired to the TPM through a PCI connector. I will set up a Linux environment for this platform to run the wolfTPM unit-test and make sure the initial bus configuration is correct and that the device is fully-functional.

------------

I don't really understand how the data must be sent through SPI. For one command should I send one burst of x bytes. Or x burst of one byte. Or something else?


Thanks for your time!

Best,
JA

Share

Re: WolfTPM_SPI_Genode_integration

Hi JA,

Typically the operation is synchronous where the write and read and happening at the same time. I believe you can get the separate write and read working, but you will have to assert the chip select between the entire transaction.

1) Assert CS
2) Write 4 byte header (ignore read)
3) Read 1 byte and check for MSB 0x80 set
4) Read or Write remainder
5) De-assert CS.

It sounds like the issue is with the SPI driver. I have not tested wolfTPM with the i.MX8Q, but we do have customers using that platform. If this is a commercial effort you might considering using our consulting services to help port. Feel free to send an email to support@wolfssl.com and mention this ticket along with your project and contact details.

Thanks,
David Garske, wolfSSL

Share