Add support for TPM2.0 modules to tpm driver
Currently, our tpm driver only supports the older TPM 1.2 spec. Most recent systems now include TPM2.0 modules. The TPM2.0 standard substantially improves upon the 1.2 spec, allowing for far more uses beyond what TPM 1.2 provides. Especially interesting is that it includes algorithm agility (i.e. new mechanisms can be added while 1.2 has a fixed, and somewhat outdated list of supported mechanisms). As part of that the PC profile (which despite the name basically means x86/amd64 systems), there are a number of required minimums in terms of capacity, mechanisms supported (including ECC and specifically the NIST P-256 and P-384 curves).
The existing interface used by TPM1.2 is compatible with 2.0, however the payloads may not be (i.e. some, perhaps most, TPM 2.0 modules may only accept TPM2.0 payloads and will return an error when presented with a TPM1.2 payload). Additionally, a second interface (CRB -- command response buffer) is defined for TPM 2.0, and a TPM2.0 module may only operate using either the older FIFO interface or the newer CRB interface (their register spaces overlap minus a small common section that can be used to determine the supported mode). All that to say that we should add support for modules that use the CRB interface as well (my understanding is that at least some hypervisors use this interface when presenting virtualized TPMs to guests).
As a part of the TPM2.0 standard, there is also a spec (TAB -- TPM Access Broker) that defines how to arbitrate between multiple clients attempting to use a TPM module. When a TPM2.0 module is present, we should support multiple clients with the kernel driver arbitrating between them. While it is possible (and permitted by the standard) to do this with a user land process, experience with similar functionality with CCID devices suggest that it cannot do as good as a job as doing it in the kernel. It should be noted this is only when a TPM2.0 module is detected. If a TPM1.2 module is detected, we will revert to the current behavior of a single consumer (i.e. one process allowed to have the device
open(2) at a time).
Since the FIFO interface may be used by both 1.2 and 2.0 clients, we should be able to have a single driver for either version of a TPM module present. This should allow existing consumers (e.g. pkcs11_tpm, tpmadm, etc) to continue to operate on systems with TPM1.2 modules. Adding support to those utilities will be left to a separate issue -- since the TPM1.2 and TPM2.0 payloads are distinct, such utilities will merely fail on systems with TPM2.0 modules (whereas today the driver cannot even attach). There is unfortunately, no manner for clients to detect the version present other than 'try a 2.0 command and a 1.2 command, see which one succeeds', but the specs are pretty explicit about returning errors (i.e. any TPM1.2 module that misbehaves when presented with a 2.0 payload is both out of spec and horribly broken).
No data to display