[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [PATCH V2 2/3] verifiers: Core TPM support
From: |
Daniel P. Smith |
Subject: |
Re: [PATCH V2 2/3] verifiers: Core TPM support |
Date: |
Sun, 18 Nov 2018 09:12:45 -0500 |
User-agent: |
Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Thunderbird/52.8.0 |
On 11/14/2018 06:24 PM, Matthew Garrett wrote:
> From: Matthew Garrett <address@hidden>
>
> Add support for performing basic TPM measurements. Right now this only
> supports extending PCRs statically and only on UEFI. In future we might
> want to have some sort of mechanism for choosing which events get logged
> to which PCRs, but this seems like a good default policy and we can wait
> to see whether anyone has a use case before adding more complexity.
>
> Signed-off-by: Matthew Garrett <address@hidden>
Hey Matthew,
Daniel asked that I review since I am working him to get TrenchBoot
related work upstream into GRUB.
> ---
> grub-core/Makefile.core.def | 7 +
> grub-core/commands/efi/tpm.c | 333 +++++++++++++++++++++++++++++++++
> grub-core/commands/tpm.c | 100 ++++++++++
> grub-core/kern/i386/efi/init.c | 1 +
> include/grub/efi/tpm.h | 196 +++++++++++++++++++
> include/grub/tpm.h | 82 ++++++++
> 6 files changed, 719 insertions(+)
> create mode 100644 grub-core/commands/efi/tpm.c
> create mode 100644 grub-core/commands/tpm.c
> create mode 100644 include/grub/efi/tpm.h
> create mode 100644 include/grub/tpm.h
>
> diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def
> index 6e2cc8444..a485f9186 100644
> --- a/grub-core/Makefile.core.def
> +++ b/grub-core/Makefile.core.def
> @@ -2377,6 +2377,13 @@ module = {
> common = commands/testspeed.c;
> };
>
> +module = {
> + name = tpm;
> + common = commands/tpm.c;
> + efi = commands/efi/tpm.c;
> + enable = efi;
> +};
> +
> module = {
> name = tr;
> common = commands/tr.c;
> diff --git a/grub-core/commands/efi/tpm.c b/grub-core/commands/efi/tpm.c
> new file mode 100644
> index 000000000..7d1424fc2
> --- /dev/null
> +++ b/grub-core/commands/efi/tpm.c
> @@ -0,0 +1,333 @@
> +/*
> + * GRUB -- GRand Unified Bootloader
> + * Copyright (C) 2018 Free Software Foundation, Inc.
> + *
> + * GRUB 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 3 of the License, or
> + * (at your option) any later version.
> + *
> + * GRUB is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
> + *
> + * EFI TPM support code.
> + */
> +
> +#include <grub/err.h>
> +#include <grub/i18n.h>
> +#include <grub/efi/api.h>
> +#include <grub/efi/efi.h>
> +#include <grub/efi/tpm.h>
> +#include <grub/mm.h>
> +#include <grub/tpm.h>
> +#include <grub/term.h>
> +
> +typedef TCG_PCR_EVENT grub_tpm_event_t;
> +
> +static grub_efi_guid_t tpm_guid = EFI_TPM_GUID;
> +static grub_efi_guid_t tpm2_guid = EFI_TPM2_GUID;
> +
> +static grub_efi_handle_t *grub_tpm_handle;
> +static grub_uint8_t grub_tpm_version;
> +
> +static grub_int8_t tpm1_present = -1;
> +static grub_int8_t tpm2_present = -1;
> +
> +static grub_efi_boolean_t
> +grub_tpm1_present (grub_efi_tpm_protocol_t * tpm)
> +{
> + grub_efi_status_t status;
> + TCG_EFI_BOOT_SERVICE_CAPABILITY caps;
> + grub_uint32_t flags;
> + grub_efi_physical_address_t eventlog, lastevent;
> +
> + if (tpm1_present != -1)
> + return (grub_efi_boolean_t) tpm1_present;
> +
> + caps.Size = (grub_uint8_t) sizeof (caps);
> +
> + status = efi_call_5 (tpm->status_check, tpm, &caps, &flags, &eventlog,
> + &lastevent);
> +
> + if (status != GRUB_EFI_SUCCESS || caps.TPMDeactivatedFlag
> + || !caps.TPMPresentFlag)
> + return tpm1_present = 0;
> +
> + return tpm1_present = 1;
> +}
> +
> +static grub_efi_boolean_t
> +grub_tpm2_present (grub_efi_tpm2_protocol_t * tpm)
> +{
> + grub_efi_status_t status;
> + EFI_TCG2_BOOT_SERVICE_CAPABILITY caps;
> +
> + caps.Size = (grub_uint8_t) sizeof (caps);
> +
> + if (tpm2_present != -1)
> + return (grub_efi_boolean_t) tpm2_present;
> +
> + status = efi_call_2 (tpm->get_capability, tpm, &caps);
> +
> + if (status != GRUB_EFI_SUCCESS || !caps.TPMPresentFlag)
> + return tpm2_present = 0;
> +
> + return tpm2_present = 1;
> +}
> +
> +static grub_efi_boolean_t
> +grub_tpm_handle_find (grub_efi_handle_t * tpm_handle,
> + grub_efi_uint8_t * protocol_version)
> +{
> + grub_efi_handle_t *handles;
> + grub_efi_uintn_t num_handles;
> +
> + if (grub_tpm_handle != NULL)
> + {
> + *tpm_handle = &grub_tpm_handle;
> + *protocol_version = grub_tpm_version;
> + return 1;
> + }
> +
> + handles = grub_efi_locate_handle (GRUB_EFI_BY_PROTOCOL, &tpm_guid, NULL,
> + &num_handles);
> + if (handles && num_handles > 0)
> + {
> + grub_tpm_handle = handles[0];
> + *tpm_handle = handles[0];
> + grub_tpm_version = 1;
> + *protocol_version = 1;
> + return 1;
> + }
> +
> + handles = grub_efi_locate_handle (GRUB_EFI_BY_PROTOCOL, &tpm2_guid, NULL,
> + &num_handles);
> + if (handles && num_handles > 0)
> + {
> + grub_tpm_handle = handles[0];
> + *tpm_handle = handles[0];
> + grub_tpm_version = 2;
> + *protocol_version = 2;
> + return 1;
> + }
> +
> + return 0;
> +}
> +
> +static grub_err_t
> +grub_tpm1_execute (grub_efi_handle_t tpm_handle,
> + PassThroughToTPM_InputParamBlock * inbuf,
> + PassThroughToTPM_OutputParamBlock * outbuf)
> +{
> + grub_efi_status_t status;
> + grub_efi_tpm_protocol_t *tpm;
> + grub_uint32_t inhdrsize = sizeof (*inbuf) - sizeof (inbuf->TPMOperandIn);
> + grub_uint32_t outhdrsize =
> + sizeof (*outbuf) - sizeof (outbuf->TPMOperandOut);
> +
> + tpm = grub_efi_open_protocol (tpm_handle, &tpm_guid,
> + GRUB_EFI_OPEN_PROTOCOL_GET_PROTOCOL);
> +
> + if (!grub_tpm1_present (tpm))
> + return 0;
> +
> + /* UEFI TPM protocol takes the raw operand block, no param block header */
> + status = efi_call_5 (tpm->pass_through_to_tpm, tpm,
> + inbuf->IPBLength - inhdrsize, inbuf->TPMOperandIn,
> + outbuf->OPBLength - outhdrsize, outbuf->TPMOperandOut);
> +
> + switch (status)
> + {
> + case GRUB_EFI_SUCCESS:
> + return 0;
> + case GRUB_EFI_DEVICE_ERROR:
> + return grub_error (GRUB_ERR_IO, N_("Command failed"));
> + case GRUB_EFI_INVALID_PARAMETER:
> + return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("Invalid parameter"));
> + case GRUB_EFI_BUFFER_TOO_SMALL:
> + return grub_error (GRUB_ERR_BAD_ARGUMENT,
> + N_("Output buffer too small"));
> + case GRUB_EFI_NOT_FOUND:
> + return grub_error (GRUB_ERR_UNKNOWN_DEVICE, N_("TPM unavailable"));
> + default:
> + return grub_error (GRUB_ERR_UNKNOWN_DEVICE, N_("Unknown TPM error"));
> + }
> +}
> +
> +static grub_err_t
> +grub_tpm2_execute (grub_efi_handle_t tpm_handle,
> + PassThroughToTPM_InputParamBlock * inbuf,
> + PassThroughToTPM_OutputParamBlock * outbuf)
> +{
> + grub_efi_status_t status;
> + grub_efi_tpm2_protocol_t *tpm;
> + grub_uint32_t inhdrsize = sizeof (*inbuf) - sizeof (inbuf->TPMOperandIn);
> + grub_uint32_t outhdrsize =
> + sizeof (*outbuf) - sizeof (outbuf->TPMOperandOut);
> +
> + tpm = grub_efi_open_protocol (tpm_handle, &tpm2_guid,
> + GRUB_EFI_OPEN_PROTOCOL_GET_PROTOCOL);
> +
> + if (!grub_tpm2_present (tpm))
> + return 0;
> +
> + /* UEFI TPM protocol takes the raw operand block, no param block header */
> + status = efi_call_5 (tpm->submit_command, tpm,
> + inbuf->IPBLength - inhdrsize, inbuf->TPMOperandIn,
> + outbuf->OPBLength - outhdrsize, outbuf->TPMOperandOut);
> +
> + switch (status)
> + {
> + case GRUB_EFI_SUCCESS:
> + return 0;
> + case GRUB_EFI_DEVICE_ERROR:
> + return grub_error (GRUB_ERR_IO, N_("Command failed"));
> + case GRUB_EFI_INVALID_PARAMETER:
> + return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("Invalid parameter"));
> + case GRUB_EFI_BUFFER_TOO_SMALL:
> + return grub_error (GRUB_ERR_BAD_ARGUMENT,
> + N_("Output buffer too small"));
> + case GRUB_EFI_NOT_FOUND:
> + return grub_error (GRUB_ERR_UNKNOWN_DEVICE, N_("TPM unavailable"));
> + default:
> + return grub_error (GRUB_ERR_UNKNOWN_DEVICE, N_("Unknown TPM error"));
> + }
> +}
> +
> +grub_err_t
> +grub_tpm_execute (PassThroughToTPM_InputParamBlock * inbuf,
> + PassThroughToTPM_OutputParamBlock * outbuf)
> +{
> + grub_efi_handle_t tpm_handle;
> + grub_uint8_t protocol_version;
> +
> + /* Absence of a TPM isn't a failure */
> + if (!grub_tpm_handle_find (&tpm_handle, &protocol_version))
> + return 0;
> +
> + if (protocol_version == 1)
> + return grub_tpm1_execute (tpm_handle, inbuf, outbuf);
> + else
> + return grub_tpm2_execute (tpm_handle, inbuf, outbuf);
> +}
> +
> +static grub_err_t
> +grub_tpm1_log_event (grub_efi_handle_t tpm_handle, unsigned char *buf,
> + grub_size_t size, grub_uint8_t pcr,
> + const char *description)
> +{
> + grub_tpm_event_t *event;
> + grub_efi_status_t status;
> + grub_efi_tpm_protocol_t *tpm;
> + grub_efi_physical_address_t lastevent;
> + grub_uint32_t algorithm;
> + grub_uint32_t eventnum = 0;
> +
> + tpm = grub_efi_open_protocol (tpm_handle, &tpm_guid,
> + GRUB_EFI_OPEN_PROTOCOL_GET_PROTOCOL);
> +
> + if (!grub_tpm1_present (tpm))
> + return 0;
> +
> + event = grub_zalloc (sizeof (*event) + grub_strlen (description) + 1);
> + if (!event)
> + return grub_error (GRUB_ERR_OUT_OF_MEMORY,
> + N_("cannot allocate TPM event buffer"));
> +
> + event->PCRIndex = pcr;
> + event->EventType = EV_IPL;
> + event->EventSize = grub_strlen (description) + 1;
> + grub_memcpy (event->Event, description, event->EventSize);
> +
> + algorithm = TCG_ALG_SHA;
> + status = efi_call_7 (tpm->log_extend_event, tpm, buf, (grub_uint64_t) size,
> + algorithm, event, &eventnum, &lastevent);
> +
> + switch (status)
> + {
> + case GRUB_EFI_SUCCESS:
> + return 0;
> + case GRUB_EFI_DEVICE_ERROR:
> + return grub_error (GRUB_ERR_IO, N_("Command failed"));
> + case GRUB_EFI_INVALID_PARAMETER:
> + return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("Invalid parameter"));
> + case GRUB_EFI_BUFFER_TOO_SMALL:
> + return grub_error (GRUB_ERR_BAD_ARGUMENT,
> + N_("Output buffer too small"));
> + case GRUB_EFI_NOT_FOUND:
> + return grub_error (GRUB_ERR_UNKNOWN_DEVICE, N_("TPM unavailable"));
> + default:
> + return grub_error (GRUB_ERR_UNKNOWN_DEVICE, N_("Unknown TPM error"));
> + }
> +}
> +
> +static grub_err_t
> +grub_tpm2_log_event (grub_efi_handle_t tpm_handle, unsigned char *buf,
> + grub_size_t size, grub_uint8_t pcr,
> + const char *description)
> +{
> + EFI_TCG2_EVENT *event;
> + grub_efi_status_t status;
> + grub_efi_tpm2_protocol_t *tpm;
> +
> + tpm = grub_efi_open_protocol (tpm_handle, &tpm2_guid,
> + GRUB_EFI_OPEN_PROTOCOL_GET_PROTOCOL);
> +
> + if (!grub_tpm2_present (tpm))
> + return 0;
> +
> + event =
> + grub_zalloc (sizeof (EFI_TCG2_EVENT) + grub_strlen (description) + 1);
> + if (!event)
> + return grub_error (GRUB_ERR_OUT_OF_MEMORY,
> + N_("cGRUBannot allocate TPM event buffer"));
> +
> + event->Header.HeaderSize = sizeof (EFI_TCG2_EVENT_HEADER);
> + event->Header.HeaderVersion = 1;
> + event->Header.PCRIndex = pcr;
> + event->Header.EventType = EV_IPL;
> + event->Size =
> + sizeof (*event) - sizeof (event->Event) + grub_strlen (description) + 1;
> + grub_memcpy (event->Event, description, grub_strlen (description) + 1);
> +
> + status = efi_call_5 (tpm->hash_log_extend_event, tpm, 0, buf,
> + (grub_uint64_t) size, event);
> +
> + switch (status)
> + {
> + case GRUB_EFI_SUCCESS:
> + return 0;
> + case GRUB_EFI_DEVICE_ERROR:
> + return grub_error (GRUB_ERR_IO, N_("Command failed"));
> + case GRUB_EFI_INVALID_PARAMETER:
> + return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("Invalid parameter"));
> + case GRUB_EFI_BUFFER_TOO_SMALL:
> + return grub_error (GRUB_ERR_BAD_ARGUMENT,
> + N_("Output buffer too small"));
> + case GRUB_EFI_NOT_FOUND:
> + return grub_error (GRUB_ERR_UNKNOWN_DEVICE, N_("TPM unavailable"));
> + default:
> + return grub_error (GRUB_ERR_UNKNOWN_DEVICE, N_("Unknown TPM error"));
> + }
> +}
> +
> +grub_err_t
> +grub_tpm_log_event (unsigned char *buf, grub_size_t size, grub_uint8_t pcr,
> + const char *description)
> +{
It would be great if the TPM commands that are using EFI protocol and
exposed to TPM command module be name spaced under efi, e.g.
grub_efi_tpm_log_event. As I lay in a TIS implementation, I can mimic a
similar set of tis name spaced functions that can be #ifdef/#else (or
any other mechanism GRUB maintainer's would prefer) switched between EFI
and TIS.
> + grub_efi_handle_t tpm_handle;
> + grub_efi_uint8_t protocol_version;
> +
> + if (!grub_tpm_handle_find (&tpm_handle, &protocol_version))
> + return 0;
> +
> + if (protocol_version == 1)
> + return grub_tpm1_log_event (tpm_handle, buf, size, pcr, description);
> + else
> + return grub_tpm2_log_event (tpm_handle, buf, size, pcr, description);
> +}
> diff --git a/grub-core/commands/tpm.c b/grub-core/commands/tpm.c
> new file mode 100644
> index 000000000..1e7fdd760
> --- /dev/null
> +++ b/grub-core/commands/tpm.c
> @@ -0,0 +1,100 @@
> +/*
> + * GRUB -- GRand Unified Bootloader
> + * Copyright (C) 2018 Free Software Foundation, Inc.
> + *
> + * GRUB 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 3 of the License, or
> + * (at your option) any later version.
> + *
> + * GRUB is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
> + *
> + * Core TPM support code.
> + */
> +
> +#include <grub/err.h>
> +#include <grub/i18n.h>
> +#include <grub/misc.h>
> +#include <grub/mm.h>
> +#include <grub/tpm.h>
> +#include <grub/term.h>
> +#include <grub/verify.h>
> +#include <grub/dl.h>
> +
> +GRUB_MOD_LICENSE ("GPLv3+") grub_err_t
> +grub_tpm_measure (unsigned char *buf, grub_size_t size, grub_uint8_t pcr,
> + const char *description)
> +{
> + return grub_tpm_log_event (buf, size, pcr, description);
> +}
> +
> +static grub_err_t
> +grub_tpm_verify_init (grub_file_t io,
> + enum grub_file_type type __attribute__ ((unused)),
> + void **context, enum grub_verify_flags *flags)
> +{
> + *context = io->name;
> + *flags |= GRUB_VERIFY_FLAGS_SINGLE_CHUNK;
> + return GRUB_ERR_NONE;
> +}
> +
> +static grub_err_t
> +grub_tpm_verify_write (void *context, void *buf, grub_size_t size)
> +{
> + return grub_tpm_measure (buf, size, GRUB_BINARY_PCR, context);
> +}
> +
> +static grub_err_t
> +grub_tpm_verify_string (char *str, enum grub_verify_string_type type)
> +{
> + const char *prefix = NULL;
> + char *description;
> + grub_err_t status;
> +
> + switch (type)
> + {
> + case GRUB_VERIFY_KERNEL_CMDLINE:
> + prefix = "kernel_cmdline: ";
> + break;
> + case GRUB_VERIFY_MODULE_CMDLINE:
> + prefix = "module_cmdline: ";
> + break;
> + case GRUB_VERIFY_COMMAND:
> + prefix = "grub_cmd: ";
> + break;
> + }
> + description = grub_malloc (grub_strlen (str) + grub_strlen (prefix) + 1);
> + if (!description)
> + return grub_errno;
> + grub_memcpy (description, prefix, grub_strlen (prefix));
> + grub_memcpy (description + grub_strlen (prefix), str,
> + grub_strlen (str) + 1);
> + status =
> + grub_tpm_measure ((unsigned char *) str, grub_strlen (str),
> + GRUB_STRING_PCR, description);
> + grub_free (description);
> + return status;
> +}
> +
> +struct grub_file_verifier grub_tpm_verifier = {
> + .name = "tpm",
> + .init = grub_tpm_verify_init,
> + .write = grub_tpm_verify_write,
> + .verify_string = grub_tpm_verify_string,
> +};
> +
> +GRUB_MOD_INIT (tpm)
> +{
> + grub_verifier_register (&grub_tpm_verifier);
> +}
> +
> +GRUB_MOD_FINI (tpm)
> +{
> + grub_verifier_unregister (&grub_tpm_verifier);
> +}
> diff --git a/grub-core/kern/i386/efi/init.c b/grub-core/kern/i386/efi/init.c
> index a28316cc6..da499aba0 100644
> --- a/grub-core/kern/i386/efi/init.c
> +++ b/grub-core/kern/i386/efi/init.c
> @@ -27,6 +27,7 @@
> #include <grub/efi/efi.h>
> #include <grub/i386/tsc.h>
> #include <grub/loader.h>
> +#include <grub/tpm.h>
>
> void
> grub_machine_init (void)
> diff --git a/include/grub/efi/tpm.h b/include/grub/efi/tpm.h
> new file mode 100644
> index 000000000..0e5e2dd36
> --- /dev/null
> +++ b/include/grub/efi/tpm.h
> @@ -0,0 +1,196 @@
> +/*
> + * GRUB -- GRand Unified Bootloader
> + * Copyright (C) 2018 Free Software Foundation, Inc.
> + *
> + * GRUB 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 3 of the License, or
> + * (at your option) any later version.
> + *
> + * GRUB is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
> + */
> +
> +#ifndef GRUB_EFI_TPM_HEADER
> +#define GRUB_EFI_TPM_HEADER 1
> +
> +#define EFI_TPM_GUID {0xf541796d, 0xa62e, 0x4954, {0xa7, 0x75, 0x95, 0x84,
> 0xf6, 0x1b, 0x9c, 0xdd }};
> +#define EFI_TPM2_GUID {0x607f766c, 0x7455, 0x42be, {0x93, 0x0b, 0xe4, 0xd7,
> 0x6d, 0xb2, 0x72, 0x0f }};
> +
> +#define TCG_ALG_SHA 0x00000004
> +
> +struct _TCG_VERSION
> +{
> + grub_efi_uint8_t Major;
> + grub_efi_uint8_t Minor;
> + grub_efi_uint8_t RevMajor;
> + grub_efi_uint8_t RevMinor;
> +};
> +typedef struct _TCG_VERSION TCG_VERSION;
> +
> +struct _TCG_EFI_BOOT_SERVICE_CAPABILITY
> +{
> + /* Size of this structure */
> + grub_efi_uint8_t Size;
> + TCG_VERSION StructureVersion;
> + TCG_VERSION ProtocolSpecVersion;
> + /* Hash algorithms supported by this TPM */
> + grub_efi_uint8_t HashAlgorithmBitmap;
> + /* 1 if TPM present */
> + char TPMPresentFlag;
> + /* 1 if TPM deactivated */
> + char TPMDeactivatedFlag;
> +};
> +typedef struct _TCG_EFI_BOOT_SERVICE_CAPABILITY
> TCG_EFI_BOOT_SERVICE_CAPABILITY;
> +
> +struct tdTCG_PCR_EVENT
> +{
> + grub_efi_uint32_t PCRIndex;
> + grub_efi_uint32_t EventType;
> + grub_efi_uint8_t digest[20];
> + grub_efi_uint32_t EventSize;
> + grub_efi_uint8_t Event[1];
> +};
> +typedef struct tdTCG_PCR_EVENT TCG_PCR_EVENT;
> +
> +struct grub_efi_tpm_protocol
> +{
> + grub_efi_status_t (*status_check) (struct grub_efi_tpm_protocol * this,
> + TCG_EFI_BOOT_SERVICE_CAPABILITY *
> + ProtocolCapability,
> + grub_efi_uint32_t * TCGFeatureFlags,
> + grub_efi_physical_address_t *
> + EventLogLocation,
> + grub_efi_physical_address_t *
> + EventLogLastEntry);
> + grub_efi_status_t (*hash_all) (struct grub_efi_tpm_protocol * this,
> + grub_efi_uint8_t * HashData,
> + grub_efi_uint64_t HashLen,
> + grub_efi_uint32_t AlgorithmId,
> + grub_efi_uint64_t * HashedDataLen,
> + grub_efi_uint8_t ** HashedDataResult);
> + grub_efi_status_t (*log_event) (struct grub_efi_tpm_protocol * this,
> + TCG_PCR_EVENT * TCGLogData,
> + grub_efi_uint32_t * EventNumber,
> + grub_efi_uint32_t Flags);
> + grub_efi_status_t (*pass_through_to_tpm) (struct grub_efi_tpm_protocol *
> + this,
> + grub_efi_uint32_t
> + TpmInputParameterBlockSize,
> + grub_efi_uint8_t *
> + TpmInputParameterBlock,
> + grub_efi_uint32_t
> + TpmOutputParameterBlockSize,
> + grub_efi_uint8_t *grub
> + TpmOutputParameterBlock);
> + grub_efi_status_t (*log_extend_event) (struct grub_efi_tpm_protocol * this,
> + grub_efi_physical_address_t HashData,
> + grub_efi_uint64_t HashDataLen,
> + grub_efi_uint32_t AlgorithmId,
> + TCG_PCR_EVENT * TCGLogData,
> + grub_efi_uint32_t * EventNumber,
> + grub_efi_physical_address_t *
> + EventLogLastEntry);
> +};
> +
> +typedef struct grub_efi_tpm_protocol grub_efi_tpm_protocol_t;
> +
> +typedef grub_efi_uint32_t EFI_TCG2_EVENT_LOG_BITMAP;
> +typedef grub_efi_uint32_t EFI_TCG2_EVENT_LOG_FORMAT;
> +typedef grub_efi_uint32_t EFI_TCG2_EVENT_ALGORITHM_BITMAP;
> +
> +struct tdEFI_TCG2_VERSION
> +{
> + grub_efi_uint8_t Major;
> + grub_efi_uint8_t Minor;
> +} GRUB_PACKED;
> +typedef struct tdEFI_TCG2_VERSION EFI_TCG2_VERSION;
> +
> +struct tdEFI_TCG2_BOOT_SERVICE_CAPABILITY
> +{
> + grub_efi_uint8_t Size;
> + EFI_TCG2_VERSION StructureVersion;
> + EFI_TCG2_VERSION ProtocolVersion;
> + EFI_TCG2_EVENT_ALGORITHM_BITMAP HashAlgorithmBitmap;
> + EFI_TCG2_EVENT_LOG_BITMAP SupportedEventLogs;
> + grub_efi_boolean_t TPMPresentFlag;
> + grub_efi_uint16_t MaxCommandSize;
> + grub_efi_uint16_t MaxResponseSize;
> + grub_efi_uint32_t ManufacturerID;
> + grub_efi_uint32_t NumberOfPcrBanks;
> + EFI_TCG2_EVENT_ALGORITHM_BITMAP ActivePcrBanks;
> +};
> +typedef struct tdEFI_TCG2_BOOT_SERVICE_CAPABILITY
> EFI_TCG2_BOOT_SERVICE_CAPABILITY;
> +
> +typedef grub_efi_uint32_t TCG_PCRINDEX;
> +typedef grub_efi_uint32_t TCG_EVENTTYPE;
> +
> +struct tdEFI_TCG2_EVENT_HEADER
> +{
> + grub_efi_uint32_t HeaderSize;
> + grub_efi_uint16_t HeaderVersion;
> + TCG_PCRINDEX PCRIndex;
> + TCG_EVENTTYPE EventType;
> +} GRUB_PACKED;
> +typedef struct tdEFI_TCG2_EVENT_HEADER EFI_TCG2_EVENT_HEADER;grub
> +
> +struct tdEFI_TCG2_EVENT
> +{
> + grub_efi_uint32_t Size;
> + EFI_TCG2_EVENT_HEADER Header;
> + grub_efi_uint8_t Event[1];
> +} GRUB_PACKED;
> +typedef struct tdEFI_TCG2_EVENT EFI_TCG2_EVENT;
> +
> +struct grub_efi_tpm2_protocol
> +{
> + grub_efi_status_t (*get_capability) (struct grub_efi_tpm2_protocol * this,
> + EFI_TCG2_BOOT_SERVICE_CAPABILITY *
> + ProtocolCapability);
> + grub_efi_status_t (*get_event_log) (struct grub_efi_tpm2_protocol * this,
> + EFI_TCG2_EVENT_LOG_FORMAT
> + EventLogFormat,
> + grub_efi_physical_address_t *
> + EventLogLocation,
> + grub_efi_physical_address_t *
> + EventLogLastEntry,
> + grub_efi_boolean_t * EventLogTruncated);
> + grub_efi_status_t (*hash_log_extend_event) (struct grub_efi_tpm2_protocol *
> + this, grub_efi_uint64_t Flags,
> + grub_efi_physical_address_t *
> + DataToHash,
> + grub_efi_uint64_t DataToHashLen,
> + EFI_TCG2_EVENT * EfiTcgEvent);
> + grub_efi_status_t (*submit_command) (struct grub_efi_tpm2_protocol * this,
> + grub_efi_uint32_t
> + InputParameterBlockSize,
> + grub_efi_uint8_t * InputParameterBlock,
> + grub_efi_uint32_t
> + OutputParameterBlockSize,
> + grub_efi_uint8_t *
> + OutputParameterBlock);
> + grub_efi_status_t (*get_active_pcr_blanks) (struct grub_efi_tpm2_protocol *
> + this,
> + grub_efi_uint32_t *
> + ActivePcrBanks);
> + grub_efi_status_t (*set_active_pcr_banks) (struct grub_efi_tpm2_protocol *
> + this,
> + grub_efi_uint32_t
> + ActivePcrBanks);
> + grub_efi_status_t (*get_result_of_set_active_pcr_banks) (struct
> +
> grub_efi_tpm2_protocol
> + * this,
> + grub_efi_uint32_t *
> + OperationPresent,
> + grub_efi_uint32_t *
> + Response);
> +};
> +
> +typedef struct grub_efi_tpm2_protocol grub_efi_tpm2_protocol_t;
> +
> +#endif
> diff --git a/include/grub/tpm.h b/include/grub/tpm.h
> new file mode 100644
> index 000000000..6a8a80225
> --- /dev/null
> +++ b/include/grub/tpm.h
> @@ -0,0 +1,82 @@
> +/*
> + * GRUB -- GRand Unified Bootloader
> + * Copyright (C) 2018 Free Software Foundation, Inc.
> + *
> + * GRUB 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 3 of the License, or
> + * (at your option) any later version.
> + *
> + * GRUB is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
> + */
> +
> +#ifndef GRUB_TPM_HEADER
> +#define GRUB_TPM_HEADER 1
> +
> +#define GRUB_STRING_PCR 8
> +#define GRUB_BINARY_PCR 9
> +
> +#define SHA1_DIGEST_SIZE 20
> +
> +#define TPM_BASE 0x0
> +#define TPM_SUCCESS TPM_BASE
> +#define TPM_AUTHFAIL (TPM_BASE + 0x1)
> +#define TPM_BADINDEX (TPM_BASE + 0x2)
> +
> +#define TPM_TAG_RQU_COMMAND 0x00C1
> +#define TPM_ORD_Extend 0x14
> +
> +#define EV_IPL 0x0d
> +
> +/* TCG_PassThroughToTPM Input Parameter Block */
> +typedef struct
> +{
> + grub_uint16_t IPBLength;
> + grub_uint16_t Reserved1;
> + grub_uint16_t OPBLength;
> + grub_uint16_t Reserved2;
> + grub_uint8_t TPMOperandIn[1];
> +} GRUB_PACKED PassThroughToTPM_InputParamBlock;
> +
> +/* TCG_PassThroughToTPM Output Parameter Block */
> +typedef struct
> +{
> + grub_uint16_t OPBLength;
> + grub_uint16_t Reserved;
> + grub_uint8_t TPMOperandOut[1];
> +} GRUB_PACKED PassThroughToTPM_OutputParamBlock;
> +
> +typedef struct
> +{
> + grub_uint16_t tag;
> + grub_uint32_t paramSize;
> + grub_uint32_t ordinal;
> + grub_uint32_t pcrNum;
> + /* The 160 bit value representing the event to be recorded. */
> + grub_uint8_t inDigest[SHA1_DIGEST_SIZE];
> +} GRUB_PACKED ExtendIncoming;
> +
> +/* TPM_Extend Outgoing Operand */
> +typedef struct
> +{
> + grub_uint16_t tag;
> + grub_uint32_t paramSize;
> + grub_uint32_t returnCode;
> + /* The PCR value after execution of the command. */
> + grub_uint8_t outDigest[SHA1_DIGEST_SIZE];
> +} GRUB_PACKED ExtendOutgoing;
> +
> +grub_err_t grub_tpm_measure (unsigned char *buf, grub_size_t size,
> + grub_uint8_t pcr, const char *description);
> +grub_err_t grub_tpm_init (void);
> +grub_err_t grub_tpm_execute (PassThroughToTPM_InputParamBlock * inbuf,
> + PassThroughToTPM_OutputParamBlock * outbuf);
> +grub_err_t grub_tpm_log_event (unsigned char *buf, grub_size_t size,
> + grub_uint8_t pcr, const char *description);
> +#endif
>
Outside of the one comment that would make my life simplier, the patch
set looks good. Please feel free to add a RB address@hidden
V/r,
Daniel Smith
- [PATCH V2 1/3] verifiers: Verify commands executed by grub, Matthew Garrett, 2018/11/14
- [PATCH V2 3/3] verifiers: Add TPM documentation, Matthew Garrett, 2018/11/14
- [PATCH V2 2/3] verifiers: Core TPM support, Matthew Garrett, 2018/11/14
- Re: [PATCH V2 2/3] verifiers: Core TPM support,
Daniel P. Smith <=
- Re: [PATCH V2 2/3] verifiers: Core TPM support, Matthew Garrett, 2018/11/19
- Re: [PATCH V2 2/3] verifiers: Core TPM support, Daniel Kiper, 2018/11/21
- Re: [PATCH V2 2/3] verifiers: Core TPM support, Matthew Garrett, 2018/11/26
- Re: [PATCH V2 2/3] verifiers: Core TPM support, Daniel Kiper, 2018/11/27
- Re: [PATCH V2 2/3] verifiers: Core TPM support, Matthew Garrett, 2018/11/29
- Re: [PATCH V2 2/3] verifiers: Core TPM support, Matthew Garrett, 2018/11/26
Re: [PATCH V2 2/3] verifiers: Core TPM support, Daniel Kiper, 2018/11/19