[SeaBIOS] [PATCH 1/3] tpm: Retrieve the PCR Bank configuration

Kevin O'Connor kevin at koconnor.net
Tue Jul 19 21:05:13 CEST 2016


On Tue, Jul 19, 2016 at 01:41:54PM -0400, Stefan Berger wrote:
> Implement tpm20_get_capability and retrieve the PCR Bank configuration
> from the TPM using this function.
> 
> Signed-off-by: Stefan Berger <stefanb at linux.vnet.ibm.com>
> ---
>  src/std/tcg.h | 29 +++++++++++++++++++++++++++++
>  src/tcgbios.c | 53 +++++++++++++++++++++++++++++++++++++++++++++++++++++
>  2 files changed, 82 insertions(+)
> 
> diff --git a/src/std/tcg.h b/src/std/tcg.h
> index c59f671..d60ee09 100644
> --- a/src/std/tcg.h
> +++ b/src/std/tcg.h
> @@ -394,12 +394,16 @@ struct tpm_res_sha1complete {
>  #define TPM2_CC_SelfTest            0x143
>  #define TPM2_CC_Startup             0x144
>  #define TPM2_CC_StirRandom          0x146
> +#define TPM2_CC_GetCapability       0x17a
>  #define TPM2_CC_GetRandom           0x17b
>  #define TPM2_CC_PCR_Extend          0x182
>  
>  /* TPM 2 error codes */
>  #define TPM2_RC_INITIALIZE          0x100
>  
> +/* TPM 2 Capabilities */
> +#define TPM2_CAP_PCRS               0x00000005
> +
>  /* TPM 2 data structures */
>  
>  struct tpm2b_stir {
> @@ -475,6 +479,31 @@ struct tpm2_req_hierarchycontrol {
>      u8 state;
>  } PACKED;
>  
> +struct tpm2_req_getcapability {
> +    struct tpm_req_header hdr;
> +    u32 capability;
> +    u32 property;
> +    u32 propertycount;
> +} PACKED;
> +
> +struct tpm2_res_getcapability {
> +    struct tpm_rsp_header hdr;
> +    u8 moreData;
> +    u32 capability;
> +    u8 data[0]; /* capability dependent data */
> +} PACKED;
> +
> +struct tpms_pcr_selection {
> +    u16 hashAlg;
> +    u8 sizeOfSelect;
> +    u8 pcrSelect[0];
> +} PACKED;
> +
> +struct tpml_pcr_selection {
> +    u32 count;
> +    struct tpms_pcr_selection selections[0];
> +} PACKED;
> +
>  /* TPM 2 log entry */
>  
>  struct tpml_digest_values_sha1 {
> diff --git a/src/tcgbios.c b/src/tcgbios.c
> index 334d99b..a79b880 100644
> --- a/src/tcgbios.c
> +++ b/src/tcgbios.c
> @@ -24,6 +24,7 @@
>  #include "tcgbios.h"// tpm_*, prototypes
>  #include "util.h" // printf, get_keystroke
>  #include "stacks.h" // wait_threads, reset
> +#include "malloc.h" // malloc_high
>  
>  /****************************************************************
>   * TPM 1.2 commands
> @@ -76,6 +77,9 @@ static int TPM_has_physical_presence;
>  
>  static TPMVersion TPM_version;
>  
> +static u32 tpm20_pcr_selection_size;
> +static struct tpml_pcr_selection *tpm20_pcr_selection;
> +
>  static struct tcpa_descriptor_rev2 *
>  find_tcpa_by_rsdp(struct rsdp_descriptor *rsdp)
>  {
> @@ -669,6 +673,51 @@ err_exit:
>  }
>  
>  static int
> +tpm20_getcapability(u32 capability, u32 property, u32 count,
> +                    struct tpm_rsp_header *rsp, u32 rsize)
> +{
> +    struct tpm2_req_getcapability trg = {
> +        .hdr.tag = cpu_to_be16(TPM2_ST_NO_SESSIONS),
> +        .hdr.totlen = cpu_to_be32(sizeof(trg)),
> +        .hdr.ordinal = cpu_to_be32(TPM2_CC_GetCapability),
> +        .capability = cpu_to_be32(capability),
> +        .property = cpu_to_be32(property),
> +        .propertycount = cpu_to_be32(count),
> +    };
> +
> +    u32 resp_size = rsize;
> +    int ret = tpmhw_transmit(0, &trg.hdr, rsp, &resp_size,
> +                             TPM_DURATION_TYPE_SHORT);
> +    ret = (ret ||
> +           rsize < be32_to_cpu(rsp->totlen)) ? -1 : be32_to_cpu(rsp->errcode);
> +
> +    dprintf(DEBUG_tcg, "TCGBIOS: Return value from sending TPM2_CC_GetCapability = 0x%08x\n",
> +            ret);
> +
> +    return ret;
> +}
> +
> +static int
> +tpm20_get_pcrbanks(void)
> +{
> +    u8 buffer[128];
> +    struct tpm2_res_getcapability *trg =
> +      (struct tpm2_res_getcapability *)&buffer;
> +
> +    int ret = tpm20_getcapability(TPM2_CAP_PCRS, 0, 8, &trg->hdr,
> +                                  sizeof(buffer));
> +    if (ret)
> +        return ret;
> +
> +    tpm20_pcr_selection_size = be32_to_cpu(trg->hdr.totlen) -
> +                               offsetof(struct tpm2_res_getcapability, data);
> +    tpm20_pcr_selection = malloc_high(tpm20_pcr_selection_size);
> +    memcpy(tpm20_pcr_selection, &trg->data, tpm20_pcr_selection_size);

It's necessary to check the result of malloc_high() for NULL.
(Otherwise, the memcpy could overwrite the memory at address zero,
which is the real-mode IDT.)

-Kevin



More information about the SeaBIOS mailing list