[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