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 <stef...@linux.ibm.com>
> Signed-off-by: Hernan Gatta <hega...@linux.microsoft.com>
> Signed-off-by: Gary Lin <g...@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.

> + *  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.

> +  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.

> +                       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...

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

Daniel

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

_______________________________________________
Grub-devel mailing list
Grub-devel@gnu.org
https://lists.gnu.org/mailman/listinfo/grub-devel

Reply via email to