[SeaBIOS] [PATCH v2 10/10] tpm: Write logs in TPM 2 format
Kevin O'Connor
kevin at koconnor.net
Mon Feb 1 23:05:16 CET 2016
On Fri, Jan 22, 2016 at 05:47:20PM -0500, Stefan Berger wrote:
> From: Stefan Berger <stefanb at linux.vnet.ibm.com>
>
> Introduce a log_entry 'object' that we use to hold the data to be logged in
> one log entry. Pass this object around rather than the TPM 1.2 specific 'pcpes'
> structure.
>
> Write this log_entry in the format that is appropriate for the version of the
> host's TPM. For TPM 1.2 write it in the 'pcpes' structure's format, for TPM 2
> in the new TPM 2 format.
>
> By using this method we can keep the API interface on systems with a TPM 2 even
> though applications pass in the 'pcpes' structures directly. The log will still be
> written in the appropriate format.
>
> The TPM 2 log contains a TPM 1.2 type of entry of event type EV_NO_ACTION and
> entry of type TCG_EfiSpeIdEventStruct as the first entry. This is described
> in the EFI specification (section 5.3):
>
> TCG EFI Protocol Specification for TPM Family 2.0
>
> http://www.trustedcomputinggroup.org/resources/tcg_efi_protocol_specification
>
>
> Signed-off-by: Stefan Berger <stefanb at linux.vnet.ibm.com>
> ---
> src/std/tcg.h | 35 ++++++++++++
> src/tcgbios.c | 173 +++++++++++++++++++++++++++++++++++++++++++++++++---------
> 2 files changed, 183 insertions(+), 25 deletions(-)
>
> diff --git a/src/std/tcg.h b/src/std/tcg.h
> index 8466b14..1e8b250 100644
> --- a/src/std/tcg.h
> +++ b/src/std/tcg.h
> @@ -89,6 +89,7 @@ enum irq_ids {
>
> /* event types: 10.4.1 / table 11 */
> #define EV_POST_CODE 1
> +#define EV_NO_ACTION 3
> #define EV_SEPARATOR 4
> #define EV_ACTION 5
> #define EV_EVENT_TAG 6
> @@ -472,4 +473,38 @@ struct tpm2_req_hierarchycontrol {
> u8 state;
> } PACKED;
>
> +/* TPM 2 log entry */
> +
> +struct tpml_digest_values_sha1 {
> + u16 hashtype;
> + u8 sha1[SHA1_BUFSIZE];
> +};
> +
> +struct tcg_pcr_event2_sha1 {
> + u32 pcrindex;
> + u32 eventtype;
> + u32 count; /* number of digests */
> + struct tpml_digest_values_sha1 digests[1];
> + u32 eventsize;
> + u8 event[0];
> +} PACKED;
> +
> +struct TCG_EfiSpecIdEventStruct {
> + u8 signature[16];
> + u32 platformClass;
> + u8 specVersionMinor;
> + u8 specVersionMajor;
> + u8 specErrata;
> + u8 uintnSize;
> + u32 numberOfAlgorithms;
> + struct TCG_EfiSpecIdEventAlgorithmSize {
> + u16 algorithmId;
> + u16 digestSize;
> + } digestSizes[1];
> + u8 vendorInfoSize;
> + u8 vendorInfo[0];
> +};
> +
> +#define TPM_TCPA_ACPI_CLASS_CLIENT 0
> +
> #endif // tcg.h
> diff --git a/src/tcgbios.c b/src/tcgbios.c
> index f5500b1..369736c 100644
> --- a/src/tcgbios.c
> +++ b/src/tcgbios.c
> @@ -52,6 +52,71 @@ static const u8 TPM2_SelfTest_YES[] = { TPM2_YES }; /* full test */
>
> typedef u8 tpm_ppi_code;
>
> +
> +static TPMVersion TPM_version;
> +
> +/****************************************************************
> + * Log entry 'object'
> + ****************************************************************/
This section looks like it could be merged into the "ACPI TCPA table
interface" section as both sections are focused solely on logging.
> +struct log_entry {
> + u32 pcrindex;
> + u32 eventtype;
> + /* we only support SHA1 for TPM 2 */
> + u8 sha1[SHA1_BUFSIZE];
> + u32 eventdatasize;
> + const void *event; /* TPM 1.2 & 2 */
> +};
Instead of introducing 'struct log_entry' to be the superset of
tcg_pcr_event2_sha1 and pcpes, why not use tcg_pcr_event2_sha1
everywhere? That is, replace all the 'struct pcpes *' with 'struct
tcg_pcr_event2_sha1 *' and then enhance tpm_log_event() to translate
to a pcpes for older logs.
Of course, the above is assuming the log should be in an "efi" format
- see previous email on that.
[...]
> +void tpm_log_init(void)
> +{
> + struct TCG_EfiSpecIdEventStruct event = {
> + .signature = "Spec ID Event03",
> + .platformClass = TPM_TCPA_ACPI_CLASS_CLIENT,
> + .specVersionMinor = 0,
> + .specVersionMajor = 2,
> + .specErrata = 0,
> + .uintnSize = 2,
> + .numberOfAlgorithms = 1,
> + .digestSizes[0] = {
> + .algorithmId = TPM2_ALG_SHA1,
> + .digestSize = SHA1_BUFSIZE,
> + },
> + .vendorInfoSize = 0,
> + };
> + struct log_entry le = {
> + .eventtype = EV_NO_ACTION,
> + .event = &event,
> + };
> +
> + switch (TPM_version) {
> + case TPM_VERSION_NONE:
> + case TPM_VERSION_1_2:
> + break;
> + case TPM_VERSION_2:
> + /* write a 1.2 type of entry */
> + TPM_version = 1;
> + tpm_log_event(&le);
> + TPM_version = 2;
Altering the TPM_version seems ugly - I think tpm_log_event() could
take the version as a parameter to avoid that.
-Kevin
More information about the SeaBIOS
mailing list