[SeaBIOS] [PATCH 3/3] tpm: Support 2.0 TPM devices connected to a TIS host
Stephen Douthit
stephend at silicom-usa.com
Mon Feb 26 23:44:47 CET 2018
On 02/26/2018 05:09 PM, Stefan Berger wrote:
> 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 ...
I think that was a note to myself I forgot to strip out when I
dropped my debug prints. I'll change the comment back.
>>
>> 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.
Doh. That makes sense. I'll need to find a 1.2 system to test on to
avoid stupid mistakes like that.
> 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.
It might be, it wasn't clear to me if the tag could be trusted if the
return code wasn't success. The Linux tpm2_probe() code bails before
the tag comparison if tpm_transmit_cmd() returns an error.
Is there a block of QEMU code you would recommend as a reference for
probing TPMs? I'm not very familiar with that code base, and a
pointer would be handy.
> 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'.
I don't see it in my notes, I can put some debug prints back in
tomorrow and will get back to you.
Thanks,
Steve
>>
>> - 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