[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