[SeaBIOS] [PATCH 3/3] tpm: Support 2.0 TPM devices connected to a TIS host

Stefan Berger stefanb at linux.vnet.ibm.com
Mon Feb 26 23:09:31 CET 2018


On 02/26/2018 03:37 PM, Stephen Douthit wrote:
> tis_get_tpm_version() was returning the interface version, which is always
> 1.2 since tis_probe() would have failed if the interface wasn't TIS.
>
> New version check is based on the tpm2_probe() function from the Linux
> tpm_tis driver.
>
> Signed-off-by: Stephen Douthit <stephend at silicom-usa.com>
> Tested-by: Stephen Douthit <stephend at silicom-usa.com>
> ---
>   src/hw/tpm_drivers.c | 21 +++++++++++++++------
>   src/std/tcg.h        |  1 +
>   src/tcgbios.c        |  2 +-
>   src/tcgbios.h        |  4 ++++
>   4 files changed, 21 insertions(+), 7 deletions(-)
>
> diff --git a/src/hw/tpm_drivers.c b/src/hw/tpm_drivers.c
> index 789d70a..32c34df 100644
> --- a/src/hw/tpm_drivers.c
> +++ b/src/hw/tpm_drivers.c
> @@ -11,6 +11,7 @@
>   #include "config.h" // CONFIG_TPM_TIS_SHA1THRESHOLD
>   #include "hw/tpm_drivers.h" // struct tpm_driver
>   #include "std/tcg.h" // TCG_RESPONSE_TIMEOUT
> +#include "tcgbios.h" // tpm20_getcapability
>   #include "output.h" // warn_timeout
>   #include "stacks.h" // yield
>   #include "string.h" // memcpy
> @@ -119,7 +120,7 @@ static u32 tis_probe(void)
>       if ((didvid != 0) && (didvid != 0xffffffff))
>           rc = 1;
>
> -    /* TPM 2 has an interface register */
> +    /* Low 32 bits of CRB interface register overlap TIS interface register */
>       u32 ifaceid = readl(TIS_REG(0, TIS_REG_IFACE_ID));

Since this is tis_probe, I don't think we need to mention the CRB here ...

>
>       if ((ifaceid & 0xf) != 0xf) {
> @@ -142,13 +143,21 @@ static u32 tis_probe(void)
>
>   static TPMVersion tis_get_tpm_version(void)
>   {
> -    /* TPM 2 has an interface register */
> -    u32 ifaceid = readl(TIS_REG(0, TIS_REG_IFACE_ID));
> +    u8 buffer[128];
> +    int ret;
> +    struct tpm2_res_getcapability *trg =
> +      (struct tpm2_res_getcapability *)&buffer;
> +
> +    ret = tpm20_getcapability(TPM2_CAP_TPM_PROPERTIES, cpu_to_be32(0x100),
> +                              cpu_to_be32(1), &trg->hdr, sizeof(buffer));
> +    if (ret == TPM2_RC_INITIALIZE)
> +        return TPM_VERSION_2;
> +    else if (ret)
> +        return TPM_VERSION_NONE;
I haven't tried yet, but likely this will not work for TPM 1.2 since it 
will also return an error.

Wouldn't the check for the tag below not be sufficient? We are doing 
something similar in QEMU when probing for the TPM. Here we send TPM 2 
command TPM_CC_ReadClock and check the tag for TPM 2 type and then TPM 
1.2 command TPM_ORD_GetTicks and check for TPM 1.2 tag.

Do you know what value does the InterfaceType show on your TIS? I only 
tested this with QEMU TIS and here we return 0x0 in those 4 bits, which 
means, following specs, 'FIFO interface as defined in PTP for TPM 2.0 is 
active'.

>
> -    if ((ifaceid & 0xf) == 0) {
> -        /* TPM 2 */
> +    if (cpu_to_be32(trg->hdr.tag) == TPM2_ST_NO_SESSIONS)
>           return TPM_VERSION_2;
> -    }
> +
>       return TPM_VERSION_1_2;
>   }
>
> diff --git a/src/std/tcg.h b/src/std/tcg.h
> index 09a92d8..4c07493 100644
> --- a/src/std/tcg.h
> +++ b/src/std/tcg.h
> @@ -357,6 +357,7 @@ struct tpm_res_sha1complete {
>
>   /* TPM 2 Capabilities */
>   #define TPM2_CAP_PCRS               0x00000005
> +#define TPM2_CAP_TPM_PROPERTIES     0x00000006
>
>   /* TPM 2 data structures */
>
> diff --git a/src/tcgbios.c b/src/tcgbios.c
> index 40b3028..b86bf64 100644
> --- a/src/tcgbios.c
> +++ b/src/tcgbios.c
> @@ -381,7 +381,7 @@ tpm_simple_cmd(u8 locty, u32 ordinal
>       return ret;
>   }
>
> -static int
> +int
>   tpm20_getcapability(u32 capability, u32 property, u32 count,
>                       struct tpm_rsp_header *rsp, u32 rsize)
>   {
> diff --git a/src/tcgbios.h b/src/tcgbios.h
> index 32fb941..9fc711a 100644
> --- a/src/tcgbios.h
> +++ b/src/tcgbios.h
> @@ -1,6 +1,7 @@
>   #ifndef TCGBIOS_H
>   #define TCGBIOS_H
>
> +#include "std/tcg.h" // struct tpm_rsp_header
>   #include "types.h"
>
>   struct bregs;
> @@ -15,5 +16,8 @@ void tpm_add_cdrom_catalog(const u8 *addr, u32 length);
>   void tpm_option_rom(const void *addr, u32 len);
>   int tpm_can_show_menu(void);
>   void tpm_menu(void);
> +int
> +tpm20_getcapability(u32 capability, u32 property, u32 count,
> +                    struct tpm_rsp_header *rsp, u32 rsize);
>
>   #endif /* TCGBIOS_H */





More information about the SeaBIOS mailing list