[U-Boot] [PATCH v4 00/32] Introduce TPMv2.0 support

Miquel Raynal miquel.raynal at bootlin.com
Tue May 15 09:56:56 UTC 2018

Current U-Boot supports TPM v1.2 specification. The new specification
(v2.0) is not backward compatible and renames/introduces several
functions. This series introduces the support for TPMv2.x chips.

First, some cleaning is done in TPM-related code. Then, the code is
split in two categories: generic code (common for both specifications)
and specific code (only used by one specification).

Then, basic functionalities are introduced one by one for the v2.x
specification. TPMv1 vs TPMv2 commands/support distinction is done with
Kconfig options. Drivers of only one specification can be selected at a

A new SPI driver following the TPM v2.x specification is introduced. It
has been tested on a ST TPM but should be usable with others v2.0
compliant chips.

Finally a full Python test suite is added, as well as a Sandbox driver.
Regular testing may be done through the test/py/ framework when using
real hardware as well as the Sandbox driver. The following test has run
more than 300 times without failing with my setup:

        test/py/test.py --bd <board> -k tpm2

Available commands for v2.0 TPMs are:

Two commands have been written but could not be tested (unsupported by
the TPM chosen):

With this set of function, minimal TPMv2.0 handling is possible with the
following sequence.

* First, initialize the TPM stack in U-Boot.

> tpm init

* Then send the STARTUP command to the TPM. The flag is slightly
  different between the revisions.

> tpm startup TPM2_SU_CLEAR

* To enable full TPM capabilities, continue the tests (or do them all
  again). It seems like self_test_full always waits for the operation to
  finish, while continue_self_test returns a busy state if called to

> tpm self_test full
> tpm self_test continue

* Manage passwords (force_clear also resets a lot of internal stuff).
  Olderly, TAKE OWNERSHIP == CLEAR + CHANGE AUTH. LOCKOUT is an example,
  ENDORSEMENT and PLATFORM hierarchies are available too:

> tpm clear TPM2_RH_LOCKOUT [<pw>]
> tpm change_auth TPM2_RH_LOCKOUT <new_pw> [<old_pw>]

* Dictionary Attack Mitigation (DAM) parameters can be changed. It is
  possible to reset the failure counter and disable the lockout (values
  erased after a CLEAR). It is then possible to check the parameters
  have been correctly applied.

> tpm dam_reset [<pw>]
> tpm dam_parameters 0xffff 1 0 [<pw>]
> tpm get_capability 0x0006 0x020e 0x4000000 4

* PCR policy may be changed (untested).
  PCR can be extended (no protection against packet replay yet).
  PCR can be read (the counter with the number of "extensions" is also

> tpm pcr_setauthpolicy 0 12345678901234567890123456789012 [<pw>]
> tpm pcr_read 0 0x4000000
> tpm pcr_extend 0 0x4000000


Changes since v3:
* Added Simon Glass's RB tags.
* Moved all the small fixes about lines, alignments, spellings, etc out
  of the big commit splitting the TPM code structure. Multiple commits
  have been made for these changes. Now the split is still done in one
  commit, but it is supposed to be only code moves and headers changes.
* Used map_sysmem() calls to let Sandbox run TPM commands instead of my
  hack (allocating memory on the go).
* Updated the documentation to use the new way of declaring parameters:
  s/@param x: y/@x: y/.
* Added two parameters in the chip private structure to store the number
  of PCRs and the minimum number of bytes needed to address one in a TPM
  command. This should fit all the TIS TPM2 compliant modules.
* The above change removes some (wrongly) hardcoded values.
* Changed the error path as suggested in tpm2_get_capability().
* Minor rephrasing.
* Explained in tpm2_get_capability() the offset '19'.
* Removed useless reset of rx_buf[0] in tpm_tis_spi_xfer().
* Changed the way spi_xfer return code is checked: error out on any
  value != 0 instead of just negative ones.
* Removed unused functions flagged __maybe_unused as well as well as the
  __maybe_unused flags themselves when not needed.
* Simplified the validity check of the GPIO as suggested.
* Updated the compatible property for the SPI modules (as well as the
  bindings docuementation) to be simply "tis,tpm2-spi" which should work
  with most compliant chips. Data is linked to this generic compatible
  in the TPM driver, other values may be added if needed in the future
  to fit other chips that would use different values than the current
  ones (used by Infineon SLB 9670 and ST ST33TPHF20 modules, for

Changes since v2:
* Wrote a full sandbox driver that passes _all_ the Python tests.
* Added changes in the library to support running in Sandbox.
* Did not rename the former I2C driver. Instead, will prefix new ones
  by "tpm2_" to make the distinction.
* Updated the Kconfig menu to have a clear separated view of the
  different drivers/specifications. CMD_TPM is now selected by a
  TPM_DRIVER_SELECTED boolean that is selected automatically when one
  driver at least is selected. One driver can only be selected if only
  one specification was precised (1.x or 2.x).
* Removed the styling fixes in the TPMv1.x command file as another one
  will be created.
* Removed the buffer length variable renaming as there is no need for
  it anymore.
* Split the whole architecture: for commands and library files, one
  tpm-common.c file plus one tpm-v<x>.c per specification. Same split
  for the header files. Some prototypes have been moved to
  lib/tpm-utils.h and cmd/tpm-user-utils.h depending on their use.
  This removed the need for an initialization with the right
  specification and the boilerplate coming with it.
* Commented all the TPMv2 enumerations.
* Renamed the macro U<XX>_TO_ARRAY into tpm_u<xx> as suggested.
* Dropped the buffer length name change as the files are split, there
  is no more need for such a rename.
* Added RB/AB tags.
* Used the new logging mechanism.
* Added documentation (bindings) for both drivers.
* Add the reset by GPIO in the SPI TPMv2.0 driver.
* Added a delay in the tests between the pcr_extend and the read_pcr.
* Ran the test suite a saw random errors sometimes, with a "LIB_ERROR".
  I wonder what produces these. Added traces to try to detect where it
  comes from.
* Some checkpatch.pl warnings have been left intentionally.

Changes since v1:
* Complete test suite for the TPMv2 commands in test/py/.
* s/STRINGIFY<X>/U<X>_TO_ARRAY/ (the macros had nothing to do with
  actual "stringification").
* Changed/fixed some comments.

Miquel Raynal (32):
  tpm: remove redundant blank line
  tpm: remove extra spaces between a function and its opening bracket
  tpm: substitute deprecated uint<x>_t types with their u<x> equivalent
  tpm: align arguments with open parenthesis
  tpm: use the BIT() macro where applicable
  tpm: fix spelling
  tpm: add extra blank lines between declarations and code
  tpm: add Revision ID field in the chip structure
  tpm: prepare introduction of TPMv2.x support in Kconfig
  tpm: disociate TPMv1.x specific and generic code
  tpm: add missing parameter in private data structure description
  tpm: prepare support for TPMv2.x commands
  tpm: add macros to enhance TPM commands readability
  tpm: add possible traces to analyze buffers returned by the TPM
  tpm: report driver error code to upper layer
  tpm: add TPM2_Startup command support
  tpm: add TPM2_SelfTest command support
  tpm: add TPM2_Clear command support
  tpm: add TPM2_PCR_Extend command support
  tpm: add TPM2_PCR_Read command support
  tpm: add TPM2_GetCapability command support
  tpm: add dictionary attack mitigation commands support
  tpm: add TPM2_HierarchyChangeAuth command support
  tpm: add PCR authentication commands support
  tpm: add support for TPMv2.x SPI modules
  tpm: add the possibility to reset the chip with a gpio
  doc: device-tree-bindings: add TIS TPMv2.0 SPI module info
  test/py: add TPMv2.x test suite
  tpm: add a Sandbox TPMv2.x driver
  doc: device-tree-bindings: add Sandbox TPMv2.0 module info
  sandbox: dts: add Sandbox TPMv2.x node
  configs: add TPMv2.x support in Sandbox

 arch/sandbox/dts/sandbox.dts                   |   4 +
 arch/sandbox/dts/sandbox64.dts                 |   4 +
 arch/sandbox/dts/test.dts                      |   4 +
 cmd/Kconfig                                    |  24 +-
 cmd/Makefile                                   |   4 +-
 cmd/tpm-common.c                               | 289 +++++++++++
 cmd/tpm-user-utils.h                           |  25 +
 cmd/{tpm.c => tpm-v1.c}                        | 488 ++++--------------
 cmd/tpm-v2.c                                   | 389 ++++++++++++++
 cmd/tpm_test.c                                 |   2 +-
 configs/sandbox64_defconfig                    |   1 +
 configs/sandbox_defconfig                      |   1 +
 configs/sandbox_flattree_defconfig             |   1 +
 configs/sandbox_noblk_defconfig                |   1 +
 configs/sandbox_spl_defconfig                  |   1 +
 doc/device-tree-bindings/tpm2/sandbox.txt      |  11 +
 doc/device-tree-bindings/tpm2/tis-tpm2-spi.txt |  18 +
 drivers/tpm/Kconfig                            |  83 ++-
 drivers/tpm/Makefile                           |   3 +
 drivers/tpm/tpm-uclass.c                       |   6 +-
 drivers/tpm/tpm2_tis_sandbox.c                 | 626 +++++++++++++++++++++++
 drivers/tpm/tpm2_tis_spi.c                     | 681 +++++++++++++++++++++++++
 drivers/tpm/tpm_atmel_twi.c                    |   2 +-
 drivers/tpm/tpm_tis.h                          |   1 +
 drivers/tpm/tpm_tis_infineon.c                 |   2 +-
 drivers/tpm/tpm_tis_lpc.c                      |   2 +-
 drivers/tpm/tpm_tis_sandbox.c                  |   2 +-
 drivers/tpm/tpm_tis_st33zp24_i2c.c             |   2 +-
 drivers/tpm/tpm_tis_st33zp24_spi.c             |   2 +-
 include/tpm-common.h                           | 218 ++++++++
 include/{tpm.h => tpm-v1.h}                    | 296 ++---------
 include/tpm-v2.h                               | 262 ++++++++++
 lib/Makefile                                   |   4 +-
 lib/tpm-common.c                               | 198 +++++++
 lib/tpm-utils.h                                | 102 ++++
 lib/{tpm.c => tpm-v1.c}                        | 600 +++++++---------------
 lib/tpm-v2.c                                   | 419 +++++++++++++++
 test/py/tests/test_tpm2.py                     | 234 +++++++++
 38 files changed, 3936 insertions(+), 1076 deletions(-)
 create mode 100644 cmd/tpm-common.c
 create mode 100644 cmd/tpm-user-utils.h
 rename cmd/{tpm.c => tpm-v1.c} (64%)
 create mode 100644 cmd/tpm-v2.c
 create mode 100644 doc/device-tree-bindings/tpm2/sandbox.txt
 create mode 100644 doc/device-tree-bindings/tpm2/tis-tpm2-spi.txt
 create mode 100644 drivers/tpm/tpm2_tis_sandbox.c
 create mode 100644 drivers/tpm/tpm2_tis_spi.c
 create mode 100644 include/tpm-common.h
 rename include/{tpm.h => tpm-v1.h} (60%)
 create mode 100644 include/tpm-v2.h
 create mode 100644 lib/tpm-common.c
 create mode 100644 lib/tpm-utils.h
 rename lib/{tpm.c => tpm-v1.c} (59%)
 create mode 100644 lib/tpm-v2.c
 create mode 100644 test/py/tests/test_tpm2.py


More information about the U-Boot mailing list