[SeaBIOS] [PATCH v2 10/10] tpm: Write logs in TPM 2 format

Stefan Berger stefanb at linux.vnet.ibm.com
Tue Feb 2 00:16:02 CET 2016


On 02/01/2016 05:05 PM, Kevin O'Connor wrote:
> 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.

Sure, can do that also.

>
> Of course, the above is assuming the log should be in an "efi" format
> - see previous email on that.


The format doesn't depend on the kind of firmware (efi vs. bios), it's 
more a TPM 2 type of log that supports different types of hashes per 
measurement.


>
> [...]
>> +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.

:-)

    Stefan




More information about the SeaBIOS mailing list