grub-devel
[Top][All Lists]
Advanced

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

Re: [PATCH v18 15/25] tss2: Add TPM2 Software Stack (TSS2) support


From: Gary Lin
Subject: Re: [PATCH v18 15/25] tss2: Add TPM2 Software Stack (TSS2) support
Date: Tue, 27 Aug 2024 14:54:58 +0800

On Thu, Aug 22, 2024 at 04:30:46PM +0200, Daniel Kiper wrote:
> On Fri, Jun 28, 2024 at 04:18:58PM +0800, Gary Lin via Grub-devel wrote:
> > A Trusted Platform Module (TPM) Software Stack (TSS) provides logic to
> > compose and submit TPM commands and parse reponses.
> >
> > A limited number of TPM commands may be accessed via the EFI TCG2
> > protocol. This protocol exposes functionality that is primarily geared
> > toward TPM usage within the context of Secure Boot. For all other TPM
> > commands, however, such as sealing and unsealing, this protocol does not
> > provide any help, with the exception of passthrough command submission.
> >
> > The SubmitCommand method allows a caller to send raw commands to the
> > system's TPM and to receive the corresponding response. These
> > command/response pairs are formatted using the TPM wire protocol. To
> > construct commands in this way, and to parse the TPM's response, it is
> > necessary to, first, possess knowledge of the various TPM structures, and,
> > second, of the TPM wire protocol itself.
> >
> > As such, this patch includes implementations of various TPM2_* functions
> > (inventoried below), and logic to write and read command and response
> > buffers, respectively, using the TPM wire protocol.
> >
> > Functions: TPM2_Create, TPM2_CreatePrimary, TPM2_EvictControl,
> > TPM2_FlushContext, TPM2_Load, TPM2_PCR_Read, TPM2_PolicyGetDigest,
> > TPM2_PolicyPCR, TPM2_ReadPublic, TPM2_StartAuthSession, TPM2_Unseal,
> > TPM2_LoadExternal, TPM2_Hash, TPM2_VerifySignature,
> > TPM2_PolicyAuthorize, TPM2_TestParms
> >
> > Cc: Stefan Berger <stefanb@linux.ibm.com>
> > Signed-off-by: Hernan Gatta <hegatta@linux.microsoft.com>
> > Signed-off-by: Gary Lin <glin@suse.com>
> > ---
> >  grub-core/Makefile.core.def   |   11 +
> >  grub-core/lib/efi/tcg2.c      |  144 +++++
> >  grub-core/lib/tss2/tcg2.h     |   35 ++
> >  grub-core/lib/tss2/tpm2_cmd.c | 1054 +++++++++++++++++++++++++++++++++
> >  grub-core/lib/tss2/tpm2_cmd.h |  157 +++++
> >  grub-core/lib/tss2/tss2.c     |   21 +
> >  6 files changed, 1422 insertions(+)
> >  create mode 100644 grub-core/lib/efi/tcg2.c
> >  create mode 100644 grub-core/lib/tss2/tcg2.h
> >  create mode 100644 grub-core/lib/tss2/tpm2_cmd.c
> >  create mode 100644 grub-core/lib/tss2/tpm2_cmd.h
> >  create mode 100644 grub-core/lib/tss2/tss2.c
> >
> > diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def
> > index 5ba9c8548..b1865d3e1 100644
> > --- a/grub-core/Makefile.core.def
> > +++ b/grub-core/Makefile.core.def
> > @@ -2567,6 +2567,17 @@ module = {
> >    enable = efi;
> >  };
> >
> > +module = {
> > +  name = tss2;
> > +  common = lib/tss2/buffer.c;
> > +  common = lib/tss2/tss2_mu.c;
> > +  common = lib/tss2/tpm2_cmd.c;
> > +  common = lib/tss2/tss2.c;
> > +  efi = lib/efi/tcg2.c;
> > +  enable = efi;
> > +  cppflags = '-I$(srcdir)/lib/tss2';
> > +};
> > +
> >  module = {
> >    name = tr;
> >    common = commands/tr.c;
> > diff --git a/grub-core/lib/efi/tcg2.c b/grub-core/lib/efi/tcg2.c
> > new file mode 100644
> > index 000000000..b15546f62
> > --- /dev/null
> > +++ b/grub-core/lib/efi/tcg2.c
> > @@ -0,0 +1,144 @@
> > +/*
> > + *  GRUB  --  GRand Unified Bootloader
> > + *  Copyright (C) 2024 Free Software Foundation, Inc.
> > + *  Copyright (C) 2022 Microsoft Corporation
> 
> Wrong order... I will not comment these mistakes any longer but all of
> them have to fixed.
> 
Sorry for that. The order issues are fixed in my WIP branch.

> > + *  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/>.
> > + */
> > +
> > +#include <grub/efi/api.h>
> > +#include <grub/efi/efi.h>
> > +#include <grub/efi/tpm.h>
> > +#include <grub/mm.h>
> > +
> > +#include <tcg2.h>
> > +
> > +static grub_err_t
> > +grub_tcg2_get_caps (grub_efi_tpm2_protocol_t *protocol, int *tpm2,
> > +               grub_size_t *max_output_size)
> > +{
> > +  grub_efi_status_t status;
> > +  static int has_caps = 0;
> 
> Please use bool instead.
> 
Sure.

> > +  static EFI_TCG2_BOOT_SERVICE_CAPABILITY caps =
> > +  {
> > +    .Size = (grub_uint8_t) sizeof (caps)
> > +  };
> > +
> > +  if (has_caps)
> > +    goto exit;
> > +
> > +  status = protocol->get_capability (protocol, &caps);
> > +  if (status != GRUB_EFI_SUCCESS || !caps.TPMPresentFlag)
> > +    return GRUB_ERR_FILE_NOT_FOUND;
> > +
> > +  has_caps = 1;
> > +
> > + exit:
> > +  if (tpm2 != NULL)
> > +    *tpm2 = caps.TPMPresentFlag;
> > +  if (max_output_size != NULL)
> > +    *max_output_size = caps.MaxResponseSize;
> > +
> > +  return GRUB_ERR_NONE;
> > +}
> 
> [...]
> 
> > diff --git a/grub-core/lib/tss2/tpm2_cmd.c b/grub-core/lib/tss2/tpm2_cmd.c
> > new file mode 100644
> > index 000000000..5de886655
> > --- /dev/null
> > +++ b/grub-core/lib/tss2/tpm2_cmd.c
> > @@ -0,0 +1,1054 @@
> > +/*
> > + *  GRUB  --  GRand Unified Bootloader
> > + *  Copyright (C) 2024 Free Software Foundation, Inc.
> > + *  Copyright (C) 2022 Microsoft Corporation
> > + *
> > + *  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/>.
> > + */
> > +
> > +#include <grub/err.h>
> > +#include <grub/mm.h>
> > +#include <grub/misc.h>
> > +#include <grub/types.h>
> > +
> > +#include <tss2_buffer.h>
> > +#include <tss2_mu.h>
> > +#include <tss2_structs.h>
> > +#include <tcg2.h>
> > +#include <tpm2_cmd.h>
> > +
> > +static TPM_RC
> > +grub_tpm2_submit_command_real (const TPMI_ST_COMMAND_TAG tag,
> > +                          const TPM_CC commandCode,
> > +                          TPM_RC *responseCode,
> > +                          const struct grub_tpm2_buffer *in,
> > +                          struct grub_tpm2_buffer *out)
> > +{
> > +  grub_err_t err;
> > +  struct grub_tpm2_buffer buf;
> > +  TPMI_ST_COMMAND_TAG tag_out;
> > +  grub_uint32_t command_size;
> > +  grub_size_t max_output_size;
> > +
> > +  /* Marshal */
> > +  grub_tpm2_buffer_init (&buf);
> > +  grub_tpm2_buffer_pack_u16 (&buf, tag);
> > +  grub_tpm2_buffer_pack_u32 (&buf, 0);
> > +  grub_tpm2_buffer_pack_u32 (&buf, commandCode);
> > +  grub_tpm2_buffer_pack (&buf, in->data, in->size);
> > +
> > +  if (buf.error != 0)
> > +    return TPM_RC_FAILURE;
> > +
> > +  command_size = grub_swap_bytes32 (buf.size);
> > +  grub_memcpy (&buf.data[sizeof (grub_uint16_t)], &command_size,
> > +          sizeof (command_size));
> > +
> > +  /* Stay within output block limits */
> > +  err = grub_tcg2_get_max_output_size (&max_output_size);
> > +  if (err != GRUB_ERR_NONE || max_output_size > out->cap)
> > +    max_output_size = out->cap - 1;
> > +
> > +  /* Submit */
> > +  err = grub_tcg2_submit_command (buf.size, buf.data, max_output_size,
> > +                             out->data);
> > +  if (err != GRUB_ERR_NONE)
> > +    return TPM_RC_FAILURE;
> > +
> > +  /* Unmarshal */
> > +  out->size = sizeof (grub_uint16_t) + sizeof (grub_uint32_t) +
> > +         sizeof (grub_uint32_t);
> > +  grub_tpm2_buffer_unpack_u16 (out, &tag_out);
> > +  grub_tpm2_buffer_unpack_u32 (out, &command_size);
> > +  grub_tpm2_buffer_unpack_u32 (out, responseCode);
> > +  out->size = command_size;
> > +  if (out->error != 0)
> > +    return TPM_RC_FAILURE;
> > +
> > +  return TPM_RC_SUCCESS;
> > +}
> > +
> > +static TPM_RC
> > +grub_tpm2_submit_command (const TPMI_ST_COMMAND_TAG tag,
> 
> You do not need "grub_" prefix before local symbols. Please drop it here
> and there, in the other patches as well.
>
I'll revise the patches to remove the unnecessary "grub_" prefix.
 
> > +                     const TPM_CC commandCode,
> > +                     TPM_RC *responseCode,
> > +                     const struct grub_tpm2_buffer *in,
> > +                     struct grub_tpm2_buffer *out)
> > +{
> > +  TPM_RC err;
> > +  int retry_cnt = 0;
> > +
> > +  /* Catch TPM_RC_RETRY and send the command again */
> > +  do {
> > +    err = grub_tpm2_submit_command_real (tag, commandCode, responseCode,
> > +                                    in, out);
> > +    if (*responseCode != TPM_RC_RETRY)
> > +      break;
> > +
> > +    retry_cnt++;
> > +  } while (retry_cnt < 3);
> > +
> > +  return err;
> > +}
> > +
> > +TPM_RC
> > +TPM2_CreatePrimary (const TPMI_RH_HIERARCHY primaryHandle,
> 
> All global symbols should be prefixed with "grub_" or "GRUB_". [1] I think
> I saw similar problems in earlier patches as well. Please fix all these
> issues...
> 
Ok.

> If you fix all these minor issues feel free to add my RB to the patch.
> 
Thanks.

Gary Lin

> Daniel
> 
> [1] 
> https://www.gnu.org/software/grub/manual/grub-dev/grub-dev.html#Naming-Conventions



reply via email to

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