[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