forked from Minki/linux
4d23cc323c
Unlike the device driver support for TPM 1.2, the TPM 2.0 does not support the securityfs pseudo files for displaying the firmware event log. This patch enables support for providing the TPM 2.0 event log in binary form. TPM 2.0 event log supports a crypto agile format that records multiple digests, which is different from TPM 1.2. This patch enables the tpm_bios_log_setup for TPM 2.0 and adds the event log parser which understand the TPM 2.0 crypto agile format. Signed-off-by: Nayna Jain <nayna@linux.vnet.ibm.com> Reviewed-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com> Tested-by: Kenneth Goldman <kgold@linux.vnet.ibm.com> Tested-by: Stefan Berger <stefanb@linux.vnet.ibm.com> Signed-off-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
113 lines
2.5 KiB
C
113 lines
2.5 KiB
C
/*
|
|
* Copyright (C) 2005 IBM Corporation
|
|
*
|
|
* Authors:
|
|
* Seiji Munetoh <munetoh@jp.ibm.com>
|
|
* Stefan Berger <stefanb@us.ibm.com>
|
|
* Reiner Sailer <sailer@watson.ibm.com>
|
|
* Kylene Hall <kjhall@us.ibm.com>
|
|
* Nayna Jain <nayna@linux.vnet.ibm.com>
|
|
*
|
|
* Maintained by: <tpmdd-devel@lists.sourceforge.net>
|
|
*
|
|
* Access to the event log extended by the TCG BIOS of PC platform
|
|
*
|
|
* 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/seq_file.h>
|
|
#include <linux/fs.h>
|
|
#include <linux/security.h>
|
|
#include <linux/module.h>
|
|
#include <linux/slab.h>
|
|
#include <linux/acpi.h>
|
|
|
|
#include "tpm.h"
|
|
#include "tpm_eventlog.h"
|
|
|
|
struct acpi_tcpa {
|
|
struct acpi_table_header hdr;
|
|
u16 platform_class;
|
|
union {
|
|
struct client_hdr {
|
|
u32 log_max_len __packed;
|
|
u64 log_start_addr __packed;
|
|
} client;
|
|
struct server_hdr {
|
|
u16 reserved;
|
|
u64 log_max_len __packed;
|
|
u64 log_start_addr __packed;
|
|
} server;
|
|
};
|
|
};
|
|
|
|
/* read binary bios log */
|
|
int tpm_read_log_acpi(struct tpm_chip *chip)
|
|
{
|
|
struct acpi_tcpa *buff;
|
|
acpi_status status;
|
|
void __iomem *virt;
|
|
u64 len, start;
|
|
struct tpm_bios_log *log;
|
|
|
|
if (chip->flags & TPM_CHIP_FLAG_TPM2)
|
|
return -ENODEV;
|
|
|
|
log = &chip->log;
|
|
|
|
/* Unfortuntely ACPI does not associate the event log with a specific
|
|
* TPM, like PPI. Thus all ACPI TPMs will read the same log.
|
|
*/
|
|
if (!chip->acpi_dev_handle)
|
|
return -ENODEV;
|
|
|
|
/* Find TCPA entry in RSDT (ACPI_LOGICAL_ADDRESSING) */
|
|
status = acpi_get_table(ACPI_SIG_TCPA, 1,
|
|
(struct acpi_table_header **)&buff);
|
|
|
|
if (ACPI_FAILURE(status))
|
|
return -ENODEV;
|
|
|
|
switch(buff->platform_class) {
|
|
case BIOS_SERVER:
|
|
len = buff->server.log_max_len;
|
|
start = buff->server.log_start_addr;
|
|
break;
|
|
case BIOS_CLIENT:
|
|
default:
|
|
len = buff->client.log_max_len;
|
|
start = buff->client.log_start_addr;
|
|
break;
|
|
}
|
|
if (!len) {
|
|
dev_warn(&chip->dev, "%s: TCPA log area empty\n", __func__);
|
|
return -EIO;
|
|
}
|
|
|
|
/* malloc EventLog space */
|
|
log->bios_event_log = kmalloc(len, GFP_KERNEL);
|
|
if (!log->bios_event_log)
|
|
return -ENOMEM;
|
|
|
|
log->bios_event_log_end = log->bios_event_log + len;
|
|
|
|
virt = acpi_os_map_iomem(start, len);
|
|
if (!virt)
|
|
goto err;
|
|
|
|
memcpy_fromio(log->bios_event_log, virt, len);
|
|
|
|
acpi_os_unmap_iomem(virt, len);
|
|
return 0;
|
|
|
|
err:
|
|
kfree(log->bios_event_log);
|
|
log->bios_event_log = NULL;
|
|
return -EIO;
|
|
|
|
}
|