grub-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [PATCH 2/2] Core TPM support


From: Michael Chang
Subject: Re: [PATCH 2/2] Core TPM support
Date: Mon, 24 Jul 2017 19:16:45 +0800
User-agent: Mutt/1.5.24 (2015-08-30)

On Wed, Jul 05, 2017 at 02:19:57PM -0700, Matthew Garrett wrote:
> Add support for performing basic TPM measurements. Right now this only
> supports extending PCRs statically and only on UEFI.
> ---
>  grub-core/Makefile.core.def    |   7 +
>  grub-core/commands/efi/tpm.c   | 282 
> +++++++++++++++++++++++++++++++++++++++++
>  grub-core/commands/tpm.c       |  87 +++++++++++++
>  grub-core/kern/i386/efi/init.c |   1 +
>  include/grub/efi/tpm.h         | 153 ++++++++++++++++++++++
>  include/grub/tpm.h             |  74 +++++++++++
>  6 files changed, 604 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 16c4d0ea5..ca1caa1fe 100644
> --- a/grub-core/Makefile.core.def
> +++ b/grub-core/Makefile.core.def
> @@ -2375,6 +2375,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..c9fb3c133
> --- /dev/null
> +++ b/grub-core/commands/efi/tpm.c
> @@ -0,0 +1,282 @@
> +#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>
> +
> +static grub_efi_guid_t tpm_guid = EFI_TPM_GUID;
> +static grub_efi_guid_t tpm2_guid = EFI_TPM2_GUID;
> +
> +static grub_efi_boolean_t grub_tpm_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;
> +
> +  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 0;
> +
> +  return 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);
> +
> +  status = efi_call_2(tpm->get_capability, tpm, &caps);
> +
> +  if (status != GRUB_EFI_SUCCESS || !caps.TPMPresentFlag)
> +    return 0;
> +
> +  return 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;
> +
> +  handles = grub_efi_locate_handle (GRUB_EFI_BY_PROTOCOL, &tpm_guid, NULL,
> +                                 &num_handles);
> +  if (handles && num_handles > 0) {
> +    *tpm_handle = handles[0];
> +    *protocol_version = 1;
> +    return 1;
> +  }
> +
> +  handles = grub_efi_locate_handle (GRUB_EFI_BY_PROTOCOL, &tpm2_guid, NULL,
> +                                 &num_handles);
> +  if (handles && num_handles > 0) {
> +    *tpm_handle = handles[0];
> +    *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_tpm_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;
> +
> +  /* It's not a hard failure for there to be no TPM */
> +  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);
> +  }
> +}
> +
> +typedef struct {
> +     grub_uint32_t pcrindex;
> +     grub_uint32_t eventtype;
> +     grub_uint8_t digest[20];
> +     grub_uint32_t eventsize;
> +     grub_uint8_t event[1];
> +} Event;

The struct is the same with TCG_PCR_EVENT defined in efi/tpm.h, what's the
point to locally redefine here ?

> +
> +
> +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)
> +{
> +  Event *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_tpm_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_("cannot 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)
> +{
> +  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..e047b5fe0
> --- /dev/null
> +++ b/grub-core/commands/tpm.c
> @@ -0,0 +1,87 @@
> +#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, 9, context);
> +}
> +
> +static void
> +grub_tpm_verify_close (void *ctxt __attribute__ ((unused)))
> +{
> +  return;
> +}
> +
> +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), 8,
> +                          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,
> +  .close = grub_tpm_verify_close,
> +  .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..e2aff4a3c
> --- /dev/null
> +++ b/include/grub/efi/tpm.h
> @@ -0,0 +1,153 @@
> +/*
> + *  GRUB  --  GRand Unified Bootloader
> + *  Copyright (C) 2015  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 }};
> +
> +typedef struct {
> +  grub_efi_uint8_t Major;
> +  grub_efi_uint8_t Minor;
> +  grub_efi_uint8_t RevMajor;
> +  grub_efi_uint8_t RevMinor;
> +} TCG_VERSION;
> +
> +typedef struct _TCG_EFI_BOOT_SERVICE_CAPABILITY {
> +  grub_efi_uint8_t          Size;                /// Size of this structure.
> +  TCG_VERSION    StructureVersion;
> +  TCG_VERSION    ProtocolSpecVersion;
> +  grub_efi_uint8_t          HashAlgorithmBitmap; /// Hash algorithms .
> +  char        TPMPresentFlag;      /// 00h = TPM not present.
> +  char        TPMDeactivatedFlag;  /// 01h = TPM currently deactivated.
> +} TCG_EFI_BOOT_SERVICE_CAPABILITY;
> +
> +typedef struct {
> +  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];
> +} 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 
> *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;
> +
> +typedef struct tdEFI_TCG2_VERSION {
> +  grub_efi_uint8_t Major;
> +  grub_efi_uint8_t Minor;
> +} GRUB_PACKED EFI_TCG2_VERSION;
> +
> +typedef 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;
> +} EFI_TCG2_BOOT_SERVICE_CAPABILITY;
> +
> +typedef grub_efi_uint32_t TCG_PCRINDEX;
> +typedef grub_efi_uint32_t TCG_EVENTTYPE;
> +
> +typedef struct tdEFI_TCG2_EVENT_HEADER {
> +  grub_efi_uint32_t HeaderSize;
> +  grub_efi_uint16_t HeaderVersion;
> +  TCG_PCRINDEX PCRIndex;
> +  TCG_EVENTTYPE EventType;
> +} GRUB_PACKED EFI_TCG2_EVENT_HEADER;
> +
> +typedef struct tdEFI_TCG2_EVENT {
> +  grub_efi_uint32_t Size;
> +  EFI_TCG2_EVENT_HEADER Header;
> +  grub_efi_uint8_t Event[1];
> +} GRUB_PACKED 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,

According to EFI TCG Protocol specification the DataToHash should be defined as 

  grub_efi_physical_address_t DataToHash

It seems problematic to use "grub_efi_physical_address_t *" as on IA32 build
that will result in different length of address "value" (32bit vs 64bit) to the
parameters of caller and callee, likely a ABI breakage.

Thanks,
Michael

> +                                           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;
> +
> +#define TCG_ALG_SHA 0x00000004
> +
> +#endif
> diff --git a/include/grub/tpm.h b/include/grub/tpm.h
> new file mode 100644
> index 000000000..d6757b57b
> --- /dev/null
> +++ b/include/grub/tpm.h
> @@ -0,0 +1,74 @@
> +/*
> + *  GRUB  --  GRand Unified Bootloader
> + *  Copyright (C) 2015  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 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;
> +        grub_uint8_t inDigest[SHA1_DIGEST_SIZE];                /* The 160 
> bit value representing the event to be recorded. */
> +} GRUB_PACKED ExtendIncoming;
> +
> +/* TPM_Extend Outgoing Operand */
> +typedef struct {
> +        grub_uint16_t tag;
> +        grub_uint32_t paramSize;
> +        grub_uint32_t returnCode;
> +        grub_uint8_t outDigest[SHA1_DIGEST_SIZE];               /* The PCR 
> value after execution of the command. */
> +} 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
> -- 
> 2.13.2.725.g09c95d1e9-goog
> 
> 
> _______________________________________________
> Grub-devel mailing list
> address@hidden
> https://lists.gnu.org/mailman/listinfo/grub-devel



reply via email to

[Prev in Thread] Current Thread [Next in Thread]