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