From: Stefan Berger <stefanb@linux.vnet.ibm.com>
To: stefanb@linux.vnet.ibm.com, seabios@seabios.org
Cc: qemu-devel@nongnu.org
Subject: [Qemu-devel] [PATCH V5 8/9] Support for Qemu-provided measurements
Date: Wed, 06 Jul 2011 12:32:06 -0400 [thread overview]
Message-ID: <20110706163235.626679604@linux.vnet.ibm.com> (raw)
In-Reply-To: 20110706163158.459850865@linux.vnet.ibm.com
[-- Attachment #1: tcgbios_paravirt_measure.diff --]
[-- Type: text/plain, Size: 5882 bytes --]
This patch adds support for measurements provided by Qemu via the
firmware interface. In the case where Qemu was started with the -kernel,
-initrd and -append command lines, Qemu hashes the kernel and initrd files
as well as the command line parameters and provides the measurements to
SeaBIOS via the firmware interface. SeaBIOS then processes the individual
measurements and extends the TPM's PCRs as well as writes logs about those
measurements.
Signed-off-by: Stefan Berger <stefanb@linux.vnet.ibm.com>
---
src/boot.c | 1
src/paravirt.c | 14 ++++++++++
src/paravirt.h | 4 +++
src/tcgbios.c | 74 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
src/tcgbios.h | 16 ++++++++++++
5 files changed, 109 insertions(+)
Index: seabios/src/tcgbios.c
===================================================================
--- seabios.orig/src/tcgbios.c
+++ seabios/src/tcgbios.c
@@ -17,6 +17,7 @@
#include "acpi.h" // RSDP_SIGNATURE, rsdt_descriptor
#include "sha1.h" // sha1
#include "smbios.h" // get_smbios_entry_point
+#include "paravirt.h" // QEMU_CFG_KERNEL_*, QEMU_CFG_INITRD_*
static const u8 Startup_ST_CLEAR[2] = { 0x00, TPM_ST_CLEAR };
@@ -1308,6 +1309,79 @@ tcpa_smbios_measure(void)
}
+u32 tcpa_process_firmware_cfg(void)
+{
+ if (!CONFIG_TCGBIOS)
+ return 0;
+
+ if (!has_working_tpm())
+ return TCG_GENERAL_ERROR;
+
+ void *ptr = (void *)0x100000;
+ u16 ctr = 0;
+
+ u32 len = qemu_cfg_get_u32(QEMU_CFG_TPM_MEASURE_SIZE);
+
+ if (len) {
+ qemu_cfg_copy(QEMU_CFG_TPM_MEASURE_DATA, ptr, len);
+
+ TPMMsrHdr *hdr = ptr;
+ u32 idx = sizeof(*hdr);
+
+ if (hdr->rev < 1)
+ return TCG_GENERAL_ERROR;
+
+ /* since the first revision (1) we have numTPMMsrEntries */
+ while (idx < hdr->totlen && ctr < hdr->numTPMMsrEntries) {
+ TPMMsrEntry *entry = (void *)hdr + idx;
+
+ idx += entry->len;
+
+ struct hleo hleo;
+
+ u8 _pcpes[offsetof(struct pcpes, event) + 400];
+ struct pcpes *pcpes = (struct pcpes *)_pcpes;
+
+ pcpes->pcrindex = entry->pcrindex;
+ pcpes->eventtype = entry->type;
+ if (entry->eventdatasize < 400) {
+ pcpes->eventdatasize = entry->eventdatasize;
+ memcpy(&pcpes->event, &entry->event, entry->eventdatasize);
+ } else {
+ pcpes->eventdatasize = 0;
+ }
+ memcpy(pcpes->digest, entry->digest, sizeof(pcpes->digest));
+
+ struct hlei hlei = {
+ .ipblength = sizeof(hlei),
+ .hashdataptr = NULL,
+ .hashdatalen = 0,
+ .pcrindex = entry->pcrindex,
+ .logeventtype= entry->type,
+ .logdataptr = pcpes,
+ .logdatalen = pcpes->eventdatasize +
+ offsetof(struct pcpes, event),
+ };
+
+ u32 rc = hash_log_event(&hlei, &hleo);
+ if (rc)
+ goto err_exit;
+
+ rc = tpm_extend(entry->digest, entry->pcrindex);
+ if (rc)
+ goto err_exit;
+
+ ctr++;
+ }
+ }
+
+ return 0;
+
+err_exit:
+ return 1;
+}
+
+
/*
* Add a measurement to the log in support of 8.2.5.3
* Creates two log entries
Index: seabios/src/boot.c
===================================================================
--- seabios.orig/src/boot.c
+++ seabios/src/boot.c
@@ -620,6 +620,7 @@ static void
boot_rom(u32 vector)
{
printf("Booting from ROM...\n");
+ tcpa_process_firmware_cfg();
struct segoff_s so;
so.segoff = vector;
call_boot_entry(so, 0);
Index: seabios/src/paravirt.c
===================================================================
--- seabios.orig/src/paravirt.c
+++ seabios/src/paravirt.c
@@ -61,6 +61,20 @@ void qemu_cfg_port_probe(void)
dprintf(4, "qemu_cfg_present=%d\n", qemu_cfg_present);
}
+u32 qemu_cfg_get_u32(int e)
+{
+ u32 i;
+
+ qemu_cfg_read_entry(&i, e, sizeof(i));
+
+ return i;
+}
+
+void qemu_cfg_copy(int e, void *buf, int len)
+{
+ qemu_cfg_read_entry(buf, e, len);
+}
+
void qemu_cfg_get_uuid(u8 *uuid)
{
if (!qemu_cfg_present)
Index: seabios/src/paravirt.h
===================================================================
--- seabios.orig/src/paravirt.h
+++ seabios/src/paravirt.h
@@ -32,6 +32,8 @@ static inline int kvm_para_available(voi
#define QEMU_CFG_BOOT_MENU 0x0e
#define QEMU_CFG_MAX_CPUS 0x0f
#define QEMU_CFG_FILE_DIR 0x19
+#define QEMU_CFG_TPM_MEASURE_SIZE 0x1a
+#define QEMU_CFG_TPM_MEASURE_DATA 0x1b
#define QEMU_CFG_ARCH_LOCAL 0x8000
#define QEMU_CFG_ACPI_TABLES (QEMU_CFG_ARCH_LOCAL + 0)
#define QEMU_CFG_SMBIOS_ENTRIES (QEMU_CFG_ARCH_LOCAL + 1)
@@ -41,6 +43,8 @@ static inline int kvm_para_available(voi
extern int qemu_cfg_present;
void qemu_cfg_port_probe(void);
+u32 qemu_cfg_get_u32(int e);
+void qemu_cfg_copy(int e, void *buf, int len);
int qemu_cfg_show_boot_menu(void);
void qemu_cfg_get_uuid(u8 *uuid);
int qemu_cfg_irq0_override(void);
Index: seabios/src/tcgbios.h
===================================================================
--- seabios.orig/src/tcgbios.h
+++ seabios/src/tcgbios.h
@@ -376,7 +376,23 @@ u32 tcpa_ipl(enum ipltype bootcd, const
u32 tcpa_start_option_rom_scan(void);
u32 tcpa_option_rom(const void *addr, u32 len);
u32 tcpa_smbios_measure(void);
+u32 tcpa_process_firmware_cfg(void);
void tcpa_menu(void);
+typedef struct TPMMsrHdr {
+ u16 rev;
+ u32 totlen;
+ u16 numTPMMsrEntries;
+} __attribute__((packed)) TPMMsrHdr;
+
+typedef struct TPMMsrEntry {
+ u32 len;
+ u32 pcrindex;
+ u32 type;
+ u8 digest[SHA1_BUFSIZE];
+ u32 eventdatasize;
+ u32 event;
+} __attribute__((packed)) TPMMsrEntry;
+
#endif /* TCGBIOS_H */
next prev parent reply other threads:[~2011-07-06 16:57 UTC|newest]
Thread overview: 14+ messages / expand[flat|nested] mbox.gz Atom feed top
2011-07-06 16:31 [Qemu-devel] [PATCH V5 0/9] Add TPM support to SeaBIOS Stefan Berger
2011-07-06 16:31 ` [Qemu-devel] [PATCH V5 1/9] Add an implementation of a TPM TIS driver Stefan Berger
2011-07-06 16:32 ` [Qemu-devel] [PATCH V5 2/9] Provide ACPI SSDT table for TPM device + S3 resume support Stefan Berger
2011-07-06 16:32 ` [Qemu-devel] [PATCH V5 3/9] Add public get_rsdp function Stefan Berger
2011-07-06 16:32 ` [Qemu-devel] [PATCH V5 4/9] Implementation of the TCG BIOS extensions Stefan Berger
2011-07-06 16:32 ` [Qemu-devel] [PATCH V5 5/9] Support for BIOS interrupt handler Stefan Berger
2011-07-06 16:32 ` [Qemu-devel] [PATCH V5 6/9] Add measurement code to the BIOS Stefan Berger
2011-07-06 16:32 ` [Qemu-devel] [PATCH V5 7/9] Add a menu for TPM control Stefan Berger
2011-07-06 16:32 ` Stefan Berger [this message]
2011-07-06 16:32 ` [Qemu-devel] [PATCH V5 9/9] Optional tests for the TIS interface Stefan Berger
2011-07-06 22:58 ` [Qemu-devel] [SeaBIOS] [PATCH V5 0/9] Add TPM support to SeaBIOS Kevin O'Connor
2011-07-07 11:48 ` Stefan Berger
2011-07-07 12:43 ` Kevin O'Connor
2011-07-07 15:22 ` Stefan Berger
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20110706163235.626679604@linux.vnet.ibm.com \
--to=stefanb@linux.vnet.ibm.com \
--cc=qemu-devel@nongnu.org \
--cc=seabios@seabios.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).