Message ID | 20200706181953.3592084-3-stefanb@linux.vnet.ibm.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | tpm2: Make TPM2 logs accessible for non-UEFI firmware | expand |
Stefan Berger @ 2020-07-06 11:19 MST: > From: Stefan Berger <stefanb@linux.ibm.com> > > In case a TPM2 is attached, search for a TPM2 ACPI table when trying > to get the event log from ACPI. If one is found, use it to get the > start and length of the log area. This allows non-UEFI systems, such > as SeaBIOS, to pass an event log when using a TPM2. > > Signed-off-by: Stefan Berger <stefanb@linux.ibm.com> Reviewed-by: Jerry Snitselaar <jsnitsel@redhat.com> > --- > drivers/char/tpm/eventlog/acpi.c | 63 +++++++++++++++++++++----------- > 1 file changed, 42 insertions(+), 21 deletions(-) > > diff --git a/drivers/char/tpm/eventlog/acpi.c b/drivers/char/tpm/eventlog/acpi.c > index 63ada5e53f13..3633ed70f48f 100644 > --- a/drivers/char/tpm/eventlog/acpi.c > +++ b/drivers/char/tpm/eventlog/acpi.c > @@ -49,9 +49,9 @@ int tpm_read_log_acpi(struct tpm_chip *chip) > void __iomem *virt; > u64 len, start; > struct tpm_bios_log *log; > - > - if (chip->flags & TPM_CHIP_FLAG_TPM2) > - return -ENODEV; > + struct acpi_table_tpm2 *tbl; > + struct acpi_tpm2_phy *tpm2_phy; > + int format; > > log = &chip->log; > > @@ -61,23 +61,44 @@ int tpm_read_log_acpi(struct tpm_chip *chip) > 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 (chip->flags & TPM_CHIP_FLAG_TPM2) { > + status = acpi_get_table("TPM2", 1, > + (struct acpi_table_header **)&tbl); > + if (ACPI_FAILURE(status)) > + return -ENODEV; > + > + if (tbl->header.length < > + sizeof(*tbl) + sizeof(struct acpi_tpm2_phy)) > + return -ENODEV; > + > + tpm2_phy = (void *)tbl + sizeof(*tbl); > + len = tpm2_phy->log_area_minimum_length; > + > + start = tpm2_phy->log_area_start_address; > + if (!start || !len) > + return -ENODEV; > + > + format = EFI_TCG2_EVENT_LOG_FORMAT_TCG_2; > + } else { > + /* 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; > + } > + > + format = EFI_TCG2_EVENT_LOG_FORMAT_TCG_1_2; > } > if (!len) { > dev_warn(&chip->dev, "%s: TCPA log area empty\n", __func__); > @@ -98,7 +119,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 EFI_TCG2_EVENT_LOG_FORMAT_TCG_1_2; > + return format; > > err: > kfree(log->bios_event_log);
On Mon, Jul 06, 2020 at 02:19:53PM -0400, Stefan Berger wrote: > From: Stefan Berger <stefanb@linux.ibm.com> > > In case a TPM2 is attached, search for a TPM2 ACPI table when trying > to get the event log from ACPI. If one is found, use it to get the > start and length of the log area. This allows non-UEFI systems, such > as SeaBIOS, to pass an event log when using a TPM2. > > Signed-off-by: Stefan Berger <stefanb@linux.ibm.com> Do you think that QEMU with TPM 1.2 emulator turned on would be a viable way to test this? I'm anyway more worried about breaking existing TPM 1.2 functionality and that requires only QEMU without extras. /Jarkko
On Tue, Jul 07, 2020 at 02:09:18AM +0300, Jarkko Sakkinen wrote: > On Mon, Jul 06, 2020 at 02:19:53PM -0400, Stefan Berger wrote: > > From: Stefan Berger <stefanb@linux.ibm.com> > > > > In case a TPM2 is attached, search for a TPM2 ACPI table when trying > > to get the event log from ACPI. If one is found, use it to get the > > start and length of the log area. This allows non-UEFI systems, such > > as SeaBIOS, to pass an event log when using a TPM2. > > > > Signed-off-by: Stefan Berger <stefanb@linux.ibm.com> > > Do you think that QEMU with TPM 1.2 emulator turned on would be a viable > way to test this? > > I'm anyway more worried about breaking existing TPM 1.2 functionality > and that requires only QEMU without extras. BTW, you should cc your patches to all M- and R-entries in the MAINTAINERS file. Please, resend this patch set version. You can add acquired reviewed-by and tested-by tags (e.g. Jerry's) and use this tag for the patch set: "RESEND,PATCH v9". /Jarkko
On 7/6/20 7:09 PM, Jarkko Sakkinen wrote: > On Mon, Jul 06, 2020 at 02:19:53PM -0400, Stefan Berger wrote: >> From: Stefan Berger <stefanb@linux.ibm.com> >> >> In case a TPM2 is attached, search for a TPM2 ACPI table when trying >> to get the event log from ACPI. If one is found, use it to get the >> start and length of the log area. This allows non-UEFI systems, such >> as SeaBIOS, to pass an event log when using a TPM2. >> >> Signed-off-by: Stefan Berger <stefanb@linux.ibm.com> > Do you think that QEMU with TPM 1.2 emulator turned on would be a viable > way to test this? Yes. > > I'm anyway more worried about breaking existing TPM 1.2 functionality > and that requires only QEMU without extras. > > /Jarkko
Jarkko Sakkinen @ 2020-07-06 16:09 MST: > On Mon, Jul 06, 2020 at 02:19:53PM -0400, Stefan Berger wrote: >> From: Stefan Berger <stefanb@linux.ibm.com> >> >> In case a TPM2 is attached, search for a TPM2 ACPI table when trying >> to get the event log from ACPI. If one is found, use it to get the >> start and length of the log area. This allows non-UEFI systems, such >> as SeaBIOS, to pass an event log when using a TPM2. >> >> Signed-off-by: Stefan Berger <stefanb@linux.ibm.com> > > Do you think that QEMU with TPM 1.2 emulator turned on would be a viable > way to test this? > > I'm anyway more worried about breaking existing TPM 1.2 functionality > and that requires only QEMU without extras. > > /Jarkko The 1.2 bits should be functionally the same as before, right?
On Mon, Jul 06, 2020 at 07:55:26PM -0400, Stefan Berger wrote: > On 7/6/20 7:09 PM, Jarkko Sakkinen wrote: > > On Mon, Jul 06, 2020 at 02:19:53PM -0400, Stefan Berger wrote: > > > From: Stefan Berger <stefanb@linux.ibm.com> > > > > > > In case a TPM2 is attached, search for a TPM2 ACPI table when trying > > > to get the event log from ACPI. If one is found, use it to get the > > > start and length of the log area. This allows non-UEFI systems, such > > > as SeaBIOS, to pass an event log when using a TPM2. > > > > > > Signed-off-by: Stefan Berger <stefanb@linux.ibm.com> > > Do you think that QEMU with TPM 1.2 emulator turned on would be a viable > > way to test this? > > > Yes. Is the emulator bundled with QEMU or does it have to be installed separately? /Jarkko
On Mon, Jul 06, 2020 at 04:57:28PM -0700, Jerry Snitselaar wrote: > > Jarkko Sakkinen @ 2020-07-06 16:09 MST: > > > On Mon, Jul 06, 2020 at 02:19:53PM -0400, Stefan Berger wrote: > >> From: Stefan Berger <stefanb@linux.ibm.com> > >> > >> In case a TPM2 is attached, search for a TPM2 ACPI table when trying > >> to get the event log from ACPI. If one is found, use it to get the > >> start and length of the log area. This allows non-UEFI systems, such > >> as SeaBIOS, to pass an event log when using a TPM2. > >> > >> Signed-off-by: Stefan Berger <stefanb@linux.ibm.com> > > > > Do you think that QEMU with TPM 1.2 emulator turned on would be a viable > > way to test this? > > > > I'm anyway more worried about breaking existing TPM 1.2 functionality > > and that requires only QEMU without extras. > > > > /Jarkko > > The 1.2 bits should be functionally the same as before, right? Yes. You should be able to read event log with TPM 1.2 as before. /Jarkko
On 7/6/20 10:24 PM, Jarkko Sakkinen wrote: > On Mon, Jul 06, 2020 at 07:55:26PM -0400, Stefan Berger wrote: >> On 7/6/20 7:09 PM, Jarkko Sakkinen wrote: >>> On Mon, Jul 06, 2020 at 02:19:53PM -0400, Stefan Berger wrote: >>>> From: Stefan Berger <stefanb@linux.ibm.com> >>>> >>>> In case a TPM2 is attached, search for a TPM2 ACPI table when trying >>>> to get the event log from ACPI. If one is found, use it to get the >>>> start and length of the log area. This allows non-UEFI systems, such >>>> as SeaBIOS, to pass an event log when using a TPM2. >>>> >>>> Signed-off-by: Stefan Berger <stefanb@linux.ibm.com> >>> Do you think that QEMU with TPM 1.2 emulator turned on would be a viable >>> way to test this? >> >> Yes. > Is the emulator bundled with QEMU or does it have to be installed > separately? It has to be installed separately. On Fedora 31 it would just be a `sudo dnf -y install swtpm-tools` and you should be good to go with libvirt / virt-manager. > > /Jarkko
On Mon, Jul 06, 2020 at 11:08:12PM -0400, Stefan Berger wrote: > On 7/6/20 10:24 PM, Jarkko Sakkinen wrote: > > On Mon, Jul 06, 2020 at 07:55:26PM -0400, Stefan Berger wrote: > > > On 7/6/20 7:09 PM, Jarkko Sakkinen wrote: > > > > On Mon, Jul 06, 2020 at 02:19:53PM -0400, Stefan Berger wrote: > > > > > From: Stefan Berger <stefanb@linux.ibm.com> > > > > > > > > > > In case a TPM2 is attached, search for a TPM2 ACPI table when trying > > > > > to get the event log from ACPI. If one is found, use it to get the > > > > > start and length of the log area. This allows non-UEFI systems, such > > > > > as SeaBIOS, to pass an event log when using a TPM2. > > > > > > > > > > Signed-off-by: Stefan Berger <stefanb@linux.ibm.com> > > > > Do you think that QEMU with TPM 1.2 emulator turned on would be a viable > > > > way to test this? > > > > > > Yes. > > Is the emulator bundled with QEMU or does it have to be installed > > separately? > > It has to be installed separately. On Fedora 31 it would just be a `sudo dnf > -y install swtpm-tools` and you should be good to go with libvirt / > virt-manager. Is there some packaging for Debian/Ubuntu available? /Jarkko
On 7/7/20 12:03 AM, Jarkko Sakkinen wrote: > On Mon, Jul 06, 2020 at 11:08:12PM -0400, Stefan Berger wrote: >> On 7/6/20 10:24 PM, Jarkko Sakkinen wrote: >>> On Mon, Jul 06, 2020 at 07:55:26PM -0400, Stefan Berger wrote: >>>> On 7/6/20 7:09 PM, Jarkko Sakkinen wrote: >>>>> On Mon, Jul 06, 2020 at 02:19:53PM -0400, Stefan Berger wrote: >>>>>> From: Stefan Berger <stefanb@linux.ibm.com> >>>>>> >>>>>> In case a TPM2 is attached, search for a TPM2 ACPI table when trying >>>>>> to get the event log from ACPI. If one is found, use it to get the >>>>>> start and length of the log area. This allows non-UEFI systems, such >>>>>> as SeaBIOS, to pass an event log when using a TPM2. >>>>>> >>>>>> Signed-off-by: Stefan Berger <stefanb@linux.ibm.com> >>>>> Do you think that QEMU with TPM 1.2 emulator turned on would be a viable >>>>> way to test this? >>>> Yes. >>> Is the emulator bundled with QEMU or does it have to be installed >>> separately? >> It has to be installed separately. On Fedora 31 it would just be a `sudo dnf >> -y install swtpm-tools` and you should be good to go with libvirt / >> virt-manager. > Is there some packaging for Debian/Ubuntu available? So far may not be available yet. I had *experimented* with a PPA once: https://launchpad.net/~stefanberger/+archive/ubuntu/swtpm-focal > /Jarkko
On Tue, Jul 07, 2020 at 12:09:11AM -0400, Stefan Berger wrote: > On 7/7/20 12:03 AM, Jarkko Sakkinen wrote: > > On Mon, Jul 06, 2020 at 11:08:12PM -0400, Stefan Berger wrote: > > > On 7/6/20 10:24 PM, Jarkko Sakkinen wrote: > > > > On Mon, Jul 06, 2020 at 07:55:26PM -0400, Stefan Berger wrote: > > > > > On 7/6/20 7:09 PM, Jarkko Sakkinen wrote: > > > > > > On Mon, Jul 06, 2020 at 02:19:53PM -0400, Stefan Berger wrote: > > > > > > > From: Stefan Berger <stefanb@linux.ibm.com> > > > > > > > > > > > > > > In case a TPM2 is attached, search for a TPM2 ACPI table when trying > > > > > > > to get the event log from ACPI. If one is found, use it to get the > > > > > > > start and length of the log area. This allows non-UEFI systems, such > > > > > > > as SeaBIOS, to pass an event log when using a TPM2. > > > > > > > > > > > > > > Signed-off-by: Stefan Berger <stefanb@linux.ibm.com> > > > > > > Do you think that QEMU with TPM 1.2 emulator turned on would be a viable > > > > > > way to test this? > > > > > Yes. > > > > Is the emulator bundled with QEMU or does it have to be installed > > > > separately? > > > It has to be installed separately. On Fedora 31 it would just be a `sudo dnf > > > -y install swtpm-tools` and you should be good to go with libvirt / > > > virt-manager. > > Is there some packaging for Debian/Ubuntu available? > > > So far may not be available yet. I had *experimented* with a PPA once: > https://launchpad.net/~stefanberger/+archive/ubuntu/swtpm-focal There is a snap available: name: swtpm-mvo summary: Libtpms-based TPM emulator publisher: Michael Vogt (mvo) store-url: https://snapcraft.io/swtpm-mvo license: unset description: | Libtpms-based TPM emulator with socket, character device, and Linux CUSE interface. commands: - swtpm-mvo.swtpm services: swtpm-mvo.swtpm-sock: simple, enabled, active snap-id: HNl1TwHRBk3OtXQ8OriRB93FDZ6vman7 tracking: latest/edge refresh-date: today at 02:05 EEST channels: latest/stable: – latest/candidate: – latest/beta: 0.1.0 2019-07-26 (11) 3MB - latest/edge: 0.1.0 2020-07-08 (75) 3MB - installed: 0.1.0 (74) 3MB - This is the version information: ❯ swtpm-mvo.swtpm --version TPM emulator version 0.4.0, Copyright (c) 2014 IBM Corp. However, if I try to run the first example from [*], I get: ❯ swtpm-mvo.swtpm socket --tpmstate dir=/tmp/mytpm1 \ --ctrl type=unixio,path=/tmp/mytpm1/swtpm-sock \ --log level=20 swtpm: Could not open UnixIO socket: No such file or directory [*] https://www.qemu.org/docs/master/specs/tpm.html /Jarkko
On 7/8/20 10:07 AM, Jarkko Sakkinen wrote: > On Tue, Jul 07, 2020 at 12:09:11AM -0400, Stefan Berger wrote: >> On 7/7/20 12:03 AM, Jarkko Sakkinen wrote: >>> On Mon, Jul 06, 2020 at 11:08:12PM -0400, Stefan Berger wrote: >>>> On 7/6/20 10:24 PM, Jarkko Sakkinen wrote: >>>>> On Mon, Jul 06, 2020 at 07:55:26PM -0400, Stefan Berger wrote: >>>>>> On 7/6/20 7:09 PM, Jarkko Sakkinen wrote: >>>>>>> On Mon, Jul 06, 2020 at 02:19:53PM -0400, Stefan Berger wrote: >>>>>>>> From: Stefan Berger <stefanb@linux.ibm.com> >>>>>>>> >>>>>>>> In case a TPM2 is attached, search for a TPM2 ACPI table when trying >>>>>>>> to get the event log from ACPI. If one is found, use it to get the >>>>>>>> start and length of the log area. This allows non-UEFI systems, such >>>>>>>> as SeaBIOS, to pass an event log when using a TPM2. >>>>>>>> >>>>>>>> Signed-off-by: Stefan Berger <stefanb@linux.ibm.com> >>>>>>> Do you think that QEMU with TPM 1.2 emulator turned on would be a viable >>>>>>> way to test this? >>>>>> Yes. >>>>> Is the emulator bundled with QEMU or does it have to be installed >>>>> separately? >>>> It has to be installed separately. On Fedora 31 it would just be a `sudo dnf >>>> -y install swtpm-tools` and you should be good to go with libvirt / >>>> virt-manager. >>> Is there some packaging for Debian/Ubuntu available? >> >> So far may not be available yet. I had *experimented* with a PPA once: >> https://launchpad.net/~stefanberger/+archive/ubuntu/swtpm-focal > There is a snap available: > > name: swtpm-mvo > summary: Libtpms-based TPM emulator > publisher: Michael Vogt (mvo) > store-url: https://snapcraft.io/swtpm-mvo > license: unset > description: | > Libtpms-based TPM emulator with socket, character device, and Linux > CUSE interface. > commands: > - swtpm-mvo.swtpm > services: > swtpm-mvo.swtpm-sock: simple, enabled, active > snap-id: HNl1TwHRBk3OtXQ8OriRB93FDZ6vman7 > tracking: latest/edge > refresh-date: today at 02:05 EEST > channels: > latest/stable: – > latest/candidate: – > latest/beta: 0.1.0 2019-07-26 (11) 3MB - > latest/edge: 0.1.0 2020-07-08 (75) 3MB - > installed: 0.1.0 (74) 3MB - > > This is the version information: > > ❯ swtpm-mvo.swtpm --version > TPM emulator version 0.4.0, Copyright (c) 2014 IBM Corp. > > However, if I try to run the first example from [*], I get: > > ❯ swtpm-mvo.swtpm socket --tpmstate dir=/tmp/mytpm1 \ > --ctrl type=unixio,path=/tmp/mytpm1/swtpm-sock \ > --log level=20 > swtpm: Could not open UnixIO socket: No such file or directory Did you create the directory '/tmp/mytpm1' ? > [*] https://www.qemu.org/docs/master/specs/tpm.html > > /Jarkko
On Wed, Jul 08, 2020 at 10:17:17AM -0400, Stefan Berger wrote: > > ❯ swtpm-mvo.swtpm socket --tpmstate dir=/tmp/mytpm1 \ > > --ctrl type=unixio,path=/tmp/mytpm1/swtpm-sock \ > > --log level=20 > > swtpm: Could not open UnixIO socket: No such file or directory > > > Did you create the directory '/tmp/mytpm1' ? Yes. It's the socket file that it is complain because it does not exist beforehand. /Jarkko
On 7/14/20 7:20 AM, Jarkko Sakkinen wrote: > On Wed, Jul 08, 2020 at 10:17:17AM -0400, Stefan Berger wrote: >>> ❯ swtpm-mvo.swtpm socket --tpmstate dir=/tmp/mytpm1 \ >>> --ctrl type=unixio,path=/tmp/mytpm1/swtpm-sock \ >>> --log level=20 >>> swtpm: Could not open UnixIO socket: No such file or directory >> >> Did you create the directory '/tmp/mytpm1' ? > Yes. It's the socket file that it is complain because it does > not exist beforehand. The socket file is created by the swtpm program. > > /Jarkko
On Tue, Jul 14, 2020 at 08:09:03AM -0400, Stefan Berger wrote: > On 7/14/20 7:20 AM, Jarkko Sakkinen wrote: > > On Wed, Jul 08, 2020 at 10:17:17AM -0400, Stefan Berger wrote: > > > > ❯ swtpm-mvo.swtpm socket --tpmstate dir=/tmp/mytpm1 \ > > > > --ctrl type=unixio,path=/tmp/mytpm1/swtpm-sock \ > > > > --log level=20 > > > > swtpm: Could not open UnixIO socket: No such file or directory > > > > > > Did you create the directory '/tmp/mytpm1' ? > > Yes. It's the socket file that it is complain because it does > > not exist beforehand. > > > The socket file is created by the swtpm program. I got this tested with real hardware, i.e. tested that TPM 1.2 works. Tested-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com> /Jarkko
diff --git a/drivers/char/tpm/eventlog/acpi.c b/drivers/char/tpm/eventlog/acpi.c index 63ada5e53f13..3633ed70f48f 100644 --- a/drivers/char/tpm/eventlog/acpi.c +++ b/drivers/char/tpm/eventlog/acpi.c @@ -49,9 +49,9 @@ int tpm_read_log_acpi(struct tpm_chip *chip) void __iomem *virt; u64 len, start; struct tpm_bios_log *log; - - if (chip->flags & TPM_CHIP_FLAG_TPM2) - return -ENODEV; + struct acpi_table_tpm2 *tbl; + struct acpi_tpm2_phy *tpm2_phy; + int format; log = &chip->log; @@ -61,23 +61,44 @@ int tpm_read_log_acpi(struct tpm_chip *chip) 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 (chip->flags & TPM_CHIP_FLAG_TPM2) { + status = acpi_get_table("TPM2", 1, + (struct acpi_table_header **)&tbl); + if (ACPI_FAILURE(status)) + return -ENODEV; + + if (tbl->header.length < + sizeof(*tbl) + sizeof(struct acpi_tpm2_phy)) + return -ENODEV; + + tpm2_phy = (void *)tbl + sizeof(*tbl); + len = tpm2_phy->log_area_minimum_length; + + start = tpm2_phy->log_area_start_address; + if (!start || !len) + return -ENODEV; + + format = EFI_TCG2_EVENT_LOG_FORMAT_TCG_2; + } else { + /* 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; + } + + format = EFI_TCG2_EVENT_LOG_FORMAT_TCG_1_2; } if (!len) { dev_warn(&chip->dev, "%s: TCPA log area empty\n", __func__); @@ -98,7 +119,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 EFI_TCG2_EVENT_LOG_FORMAT_TCG_1_2; + return format; err: kfree(log->bios_event_log);