tpm: parse TPM event logs based on EFI table

If we are not able to retrieve the TPM event logs from the ACPI table,
check the EFI configuration table (Linux-specific GUID).

The format version of the log is now returned by the provider function.

Signed-off-by: Thiebaud Weksteen <tweek@google.com>
Reviewed-by: Jason Gunthorpe <jgunthorpe@obsidianresearch.com>
Reviewed-by: Javier Martinez Canillas <javierm@redhat.com>
Tested-by: Javier Martinez Canillas <javierm@redhat.com>
Tested-by: Jarkko Sakkinen  <jarkko.sakkinen@linux.intel.com>
Reviewed-by: Jarkko Sakkinen  <jarkko.sakkinen@linux.intel.com>
Signed-off-by: Jarkko Sakkinen  <jarkko.sakkinen@linux.intel.com>
This commit is contained in:
Thiebaud Weksteen 2017-09-20 10:13:40 +02:00 committed by Jarkko Sakkinen
parent 33b6d03469
commit 58cc1e4faf
6 changed files with 88 additions and 4 deletions

View File

@ -7,6 +7,7 @@ tpm-y := tpm-interface.o tpm-dev.o tpm-sysfs.o tpm-chip.o tpm2-cmd.o \
tpm-dev-common.o tpmrm-dev.o tpm1_eventlog.o tpm2_eventlog.o \
tpm2-space.o
tpm-$(CONFIG_ACPI) += tpm_ppi.o tpm_eventlog_acpi.o
tpm-$(CONFIG_EFI) += tpm_eventlog_efi.o
tpm-$(CONFIG_OF) += tpm_eventlog_of.o
obj-$(CONFIG_TCG_TIS_CORE) += tpm_tis_core.o
obj-$(CONFIG_TCG_TIS) += tpm_tis.o

View File

@ -589,6 +589,14 @@ static inline int tpm_read_log_of(struct tpm_chip *chip)
return -ENODEV;
}
#endif
#if defined(CONFIG_EFI)
int tpm_read_log_efi(struct tpm_chip *chip);
#else
static inline int tpm_read_log_efi(struct tpm_chip *chip)
{
return -ENODEV;
}
#endif
int tpm_bios_log_setup(struct tpm_chip *chip);
void tpm_bios_log_teardown(struct tpm_chip *chip);

View File

@ -21,6 +21,7 @@
*/
#include <linux/seq_file.h>
#include <linux/efi.h>
#include <linux/fs.h>
#include <linux/security.h>
#include <linux/module.h>
@ -371,6 +372,10 @@ static int tpm_read_log(struct tpm_chip *chip)
if (rc != -ENODEV)
return rc;
rc = tpm_read_log_efi(chip);
if (rc != -ENODEV)
return rc;
return tpm_read_log_of(chip);
}
@ -388,11 +393,13 @@ int tpm_bios_log_setup(struct tpm_chip *chip)
{
const char *name = dev_name(&chip->dev);
unsigned int cnt;
int log_version;
int rc = 0;
rc = tpm_read_log(chip);
if (rc)
if (rc < 0)
return rc;
log_version = rc;
cnt = 0;
chip->bios_dir[cnt] = securityfs_create_dir(name, NULL);
@ -404,7 +411,7 @@ int tpm_bios_log_setup(struct tpm_chip *chip)
cnt++;
chip->bin_log_seqops.chip = chip;
if (chip->flags & TPM_CHIP_FLAG_TPM2)
if (log_version == EFI_TCG2_EVENT_LOG_FORMAT_TCG_2)
chip->bin_log_seqops.seqops =
&tpm2_binary_b_measurements_seqops;
else

View File

@ -102,7 +102,7 @@ int tpm_read_log_acpi(struct tpm_chip *chip)
memcpy_fromio(log->bios_event_log, virt, len);
acpi_os_unmap_iomem(virt, len);
return 0;
return EFI_TCG2_EVENT_LOG_FORMAT_TCG_1_2;
err:
kfree(log->bios_event_log);

View File

@ -0,0 +1,66 @@
/*
* Copyright (C) 2017 Google
*
* Authors:
* Thiebaud Weksteen <tweek@google.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*
*/
#include <linux/efi.h>
#include <linux/tpm_eventlog.h>
#include "tpm.h"
/* read binary bios log from EFI configuration table */
int tpm_read_log_efi(struct tpm_chip *chip)
{
struct linux_efi_tpm_eventlog *log_tbl;
struct tpm_bios_log *log;
u32 log_size;
u8 tpm_log_version;
if (!(chip->flags & TPM_CHIP_FLAG_TPM2))
return -ENODEV;
if (efi.tpm_log == EFI_INVALID_TABLE_ADDR)
return -ENODEV;
log = &chip->log;
log_tbl = memremap(efi.tpm_log, sizeof(*log_tbl), MEMREMAP_WB);
if (!log_tbl) {
pr_err("Could not map UEFI TPM log table !\n");
return -ENOMEM;
}
log_size = log_tbl->size;
memunmap(log_tbl);
log_tbl = memremap(efi.tpm_log, sizeof(*log_tbl) + log_size,
MEMREMAP_WB);
if (!log_tbl) {
pr_err("Could not map UEFI TPM log table payload!\n");
return -ENOMEM;
}
/* malloc EventLog space */
log->bios_event_log = kmalloc(log_size, GFP_KERNEL);
if (!log->bios_event_log)
goto err_memunmap;
memcpy(log->bios_event_log, log_tbl->log, log_size);
log->bios_event_log_end = log->bios_event_log + log_size;
tpm_log_version = log_tbl->version;
memunmap(log_tbl);
return tpm_log_version;
err_memunmap:
memunmap(log_tbl);
return -ENOMEM;
}

View File

@ -76,5 +76,7 @@ int tpm_read_log_of(struct tpm_chip *chip)
memcpy(log->bios_event_log, __va(base), size);
return 0;
if (chip->flags & TPM_CHIP_FLAG_TPM2)
return EFI_TCG2_EVENT_LOG_FORMAT_TCG_2;
return EFI_TCG2_EVENT_LOG_FORMAT_TCG_1_2;
}