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:
parent
33b6d03469
commit
58cc1e4faf
6 changed files with 88 additions and 4 deletions
|
@ -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 \
|
tpm-dev-common.o tpmrm-dev.o tpm1_eventlog.o tpm2_eventlog.o \
|
||||||
tpm2-space.o
|
tpm2-space.o
|
||||||
tpm-$(CONFIG_ACPI) += tpm_ppi.o tpm_eventlog_acpi.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
|
tpm-$(CONFIG_OF) += tpm_eventlog_of.o
|
||||||
obj-$(CONFIG_TCG_TIS_CORE) += tpm_tis_core.o
|
obj-$(CONFIG_TCG_TIS_CORE) += tpm_tis_core.o
|
||||||
obj-$(CONFIG_TCG_TIS) += tpm_tis.o
|
obj-$(CONFIG_TCG_TIS) += tpm_tis.o
|
||||||
|
|
|
@ -589,6 +589,14 @@ static inline int tpm_read_log_of(struct tpm_chip *chip)
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
}
|
}
|
||||||
#endif
|
#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);
|
int tpm_bios_log_setup(struct tpm_chip *chip);
|
||||||
void tpm_bios_log_teardown(struct tpm_chip *chip);
|
void tpm_bios_log_teardown(struct tpm_chip *chip);
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <linux/seq_file.h>
|
#include <linux/seq_file.h>
|
||||||
|
#include <linux/efi.h>
|
||||||
#include <linux/fs.h>
|
#include <linux/fs.h>
|
||||||
#include <linux/security.h>
|
#include <linux/security.h>
|
||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
|
@ -371,6 +372,10 @@ static int tpm_read_log(struct tpm_chip *chip)
|
||||||
if (rc != -ENODEV)
|
if (rc != -ENODEV)
|
||||||
return rc;
|
return rc;
|
||||||
|
|
||||||
|
rc = tpm_read_log_efi(chip);
|
||||||
|
if (rc != -ENODEV)
|
||||||
|
return rc;
|
||||||
|
|
||||||
return tpm_read_log_of(chip);
|
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);
|
const char *name = dev_name(&chip->dev);
|
||||||
unsigned int cnt;
|
unsigned int cnt;
|
||||||
|
int log_version;
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
|
|
||||||
rc = tpm_read_log(chip);
|
rc = tpm_read_log(chip);
|
||||||
if (rc)
|
if (rc < 0)
|
||||||
return rc;
|
return rc;
|
||||||
|
log_version = rc;
|
||||||
|
|
||||||
cnt = 0;
|
cnt = 0;
|
||||||
chip->bios_dir[cnt] = securityfs_create_dir(name, NULL);
|
chip->bios_dir[cnt] = securityfs_create_dir(name, NULL);
|
||||||
|
@ -404,7 +411,7 @@ int tpm_bios_log_setup(struct tpm_chip *chip)
|
||||||
cnt++;
|
cnt++;
|
||||||
|
|
||||||
chip->bin_log_seqops.chip = chip;
|
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 =
|
chip->bin_log_seqops.seqops =
|
||||||
&tpm2_binary_b_measurements_seqops;
|
&tpm2_binary_b_measurements_seqops;
|
||||||
else
|
else
|
||||||
|
|
|
@ -102,7 +102,7 @@ int tpm_read_log_acpi(struct tpm_chip *chip)
|
||||||
memcpy_fromio(log->bios_event_log, virt, len);
|
memcpy_fromio(log->bios_event_log, virt, len);
|
||||||
|
|
||||||
acpi_os_unmap_iomem(virt, len);
|
acpi_os_unmap_iomem(virt, len);
|
||||||
return 0;
|
return EFI_TCG2_EVENT_LOG_FORMAT_TCG_1_2;
|
||||||
|
|
||||||
err:
|
err:
|
||||||
kfree(log->bios_event_log);
|
kfree(log->bios_event_log);
|
||||||
|
|
66
drivers/char/tpm/tpm_eventlog_efi.c
Normal file
66
drivers/char/tpm/tpm_eventlog_efi.c
Normal 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;
|
||||||
|
}
|
|
@ -76,5 +76,7 @@ int tpm_read_log_of(struct tpm_chip *chip)
|
||||||
|
|
||||||
memcpy(log->bios_event_log, __va(base), size);
|
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;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue