grub-devel
[Top][All Lists]
Advanced

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

RE: [PATCH V2] Enable TDX measurement to RTMR register


From: Lu, Ken
Subject: RE: [PATCH V2] Enable TDX measurement to RTMR register
Date: Fri, 29 Apr 2022 04:25:35 +0000

Hi Kiper, 

Thanks for your detail review! Appreciate!!

I will continue fix all your suggestions except changing Event[1] => Event[0] 
for grub_efi_cc_event_t. Actually, I think your suggestion is very nice C 
programming tip, it will be more concise and readable. 
But I am thinking how about align with the definition in UEFI now 
https://github.com/tianocore/edk2/blob/d372ab585a2cdc5348af5f701c56c631235fe698/MdePkg/Include/Protocol/CcMeasurement.h#L100.
 I will talk with UEFI owner to make same changes for Event[0] both in EFI and 
grub/shim together in future. Do you agree?

Thanks
Ken

> -----Original Message-----
> From: Grub-devel <grub-devel-bounces+ken.lu=intel.com@gnu.org> On Behalf
> Of Daniel Kiper
> Sent: Wednesday, April 27, 2022 10:37 PM
> To: Lu, Ken <ken.lu@intel.com>
> Cc: grub-devel@gnu.org; Xu, Min M <min.m.xu@intel.com>
> Subject: Re: [PATCH V2] Enable TDX measurement to RTMR register
> 
> First of all, sorry for late reply but I am busy...
> 
> On Mon, Mar 14, 2022 at 02:52:22PM +0800, Lu Ken wrote:
> > Intel Trust Domain Extensions(Intel TDX) refers to an Intel technology
> > that extends Virtual Machine Extensions(VMX) and Multi-Key Total
> > Memory
> > Encryption(MK-TME) with a new kind of virtual machine guest called a
> > Trust Domain(TD)[1]. A TD runs in a CPU mode that protects the
> > confidentiality of its memory contents and its CPU state from any
> > other software, including the hosting Virtual Machine Monitor (VMM).
> >
> > Trust Domain Virtual Firmware (TDVF) is required to provide TD
> > services to the TD guest OS.[2] Its reference code is available at
> https://github.com/tianocore/edk2-staging/tree/TDVF.
> >
> > To support TD measurement/attestation, TDs provide 4 RTMR registers
> > like
> > TPM/TPM2 PCR as below:
> > - RTMR[0] is for TDVF configuration
> > - RTMR[1] is for the TD OS loader and kernel
> > - RTMR[2] is for the OS application
> > - RTMR[3] is reserved for special usage only
> >
> > This patch adds TD Measurement protocol support along with TPM/TPM2
> protocol.
> >
> > References:
> > [1]
> > https://software.intel.com/content/dam/develop/external/us/en/document
> > s/tdx-whitepaper-v4.pdf [2]
> > https://software.intel.com/content/dam/develop/external/us/en/document
> > s/tdx-virtual-firmware-design-guide-rev-1.pdf
> >
> > Signed-off-by: Lu Ken <ken.lu@intel.com>
> > ---
> >
> > Notes:
> >     v2 changes:
> >     - Separate the CC_MEASUREMENT code to standalone file grub-
> core/commands/efi/cc.c
> >     - Use NULL explicity for the judgement like "if (cc != NULL)"
> >     - Include all headers for all types, structure used in cc.h
> >     - Add the prefix "GRUB_"for all macro definition and the prefix "grub_" 
> > for
> type or structure's field
> >     - Align one argument in one line
> >
> >  grub-core/Makefile.core.def  |   1 +
> >  grub-core/commands/efi/cc.c  |  88 +++++++++++++++++++
> >  grub-core/commands/efi/tpm.c |   3 +
> >  include/grub/efi/cc.h        | 164
> +++++++++++++++++++++++++++++++++++
> >  4 files changed, 256 insertions(+)
> >  create mode 100644 grub-core/commands/efi/cc.c  create mode 100644
> > include/grub/efi/cc.h
> >
> > diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def
> > index 6b00eb555..dbae796a7 100644
> > --- a/grub-core/Makefile.core.def
> > +++ b/grub-core/Makefile.core.def
> > @@ -2561,6 +2561,7 @@ module = {
> >    name = tpm;
> >    common = commands/tpm.c;
> >    efi = commands/efi/tpm.c;
> > +  efi = commands/efi/cc.c;
> >    enable = efi;
> >  };
> >
> > diff --git a/grub-core/commands/efi/cc.c b/grub-core/commands/efi/cc.c
> > new file mode 100644 index 000000000..0e6b417c4
> > --- /dev/null
> > +++ b/grub-core/commands/efi/cc.c
> > @@ -0,0 +1,88 @@
> > +/*
> > + *  GRUB  --  GRand Unified Bootloader
> > + *  Copyright (C) 2022  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/>.
> > + *
> > + *  EFI CC measurement support code.
> 
> You told me this feature is not Intel specific. In this case I would move 
> back this
> code to the grub-core/commands/efi/tpm.c. Sorry about that...
[Lu, Ken] Sure, I will move it.

> 
> > + */
> > +
> > +#include <grub/err.h>
> > +#include <grub/i18n.h>
> > +#include <grub/efi/api.h>
> > +#include <grub/efi/efi.h>
> > +#include <grub/efi/cc.h>
> > +#include <grub/tpm.h>
> > +#include <grub/mm.h>
> > +
> > +static grub_efi_guid_t cc_measurement_guid =
> > +GRUB_EFI_CC_MEASUREMENT_PROTOCOL_GUID;
> > +
> > +static inline grub_err_t
> 
> Please drop inline from here. Compiler will know how to optimize this function
> properly.
[Lu, Ken] Thanks for reminder, I will fix it

> 
> > +grub_efi_log_event_status (grub_efi_status_t status) {
> > +  switch (status)
> > +    {
> > +    case GRUB_EFI_SUCCESS:
> > +      return 0;
> 
> return GRUB_ERR_NONE;
[Lu, Ken] Thanks for reminder, I will fix it

> 
> > +    case GRUB_EFI_DEVICE_ERROR:
> > +      return grub_error (GRUB_ERR_IO, N_("Command failed"));
> 
> s/Command failed/command failed/
[Lu, Ken] Thanks for this, I will fix it

> 
> Most error messages should start with lowercase.
> 
> > +    case GRUB_EFI_INVALID_PARAMETER:
> > +      return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("Invalid
> > + parameter"));
> 
> s/Invalid parameter/invalid parameter/
[Lu, Ken] Thanks for this comment, I will fix it

> 
> > +    case GRUB_EFI_BUFFER_TOO_SMALL:
> > +      return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("Output buffer too
> > + small"));
> 
> Ditto.
[Lu, Ken] Thanks for this comment, I will fix it

> 
> > +    case GRUB_EFI_NOT_FOUND:
> > +      return grub_error (GRUB_ERR_UNKNOWN_DEVICE, N_("TPM
> > + unavailable"));
> 
> However, this one is OK.
> 
> > +    default:
> > +      return grub_error (GRUB_ERR_UNKNOWN_DEVICE, N_("Unknown TPM
> > + error"));
> 
> s/Unknown TPM error/unknown TPM error/
[Lu, Ken] Thanks for this comment, I will fix it

> 
> > +    }
> > +}
> > +
> > +grub_err_t
> > +grub_cc_log_event (unsigned char *buf, grub_size_t size, grub_uint8_t pcr,
> > +              const char *description)
> > +{
> > +  grub_efi_cc_event_t *event;
> > +  grub_efi_status_t status;
> > +  grub_efi_cc_protocol_t *cc;
> > +  grub_efi_cc_mr_index_t mr;
> > +
> > +  cc = grub_efi_locate_protocol (&cc_measurement_guid, NULL);
> 
> I am not convinced calling into firmware on every event is good idea. I think 
> we
> should avoid that especially if at tpm module init protocol was not 
> available. On
> the other hand if protocol was available during tpm module init is it safe to
> assume it is still available during an tpm event? If not we can call
> grub_efi_locate_protocol() on every event until return value is not NULL.
[Lu, Ken] I think this is very nice suggestion. For TPM1/TPM2/CC, they all need 
call EFI to get handle, then call EFI to open protocol.
So we should only do once for both getting handle + open protocol. So I will 
optimize code for TPM1/TPM2 and CC according to your suggestion.

> 
> > +  if (cc == NULL)
> > +    return 0;
> 
> return GRUB_ERR_NONE;
[Lu, Ken] Thanks for this comment, I will fix it

> 
> > +  status = efi_call_3 (cc->map_pcr_to_mr_index, cc, pcr, &mr);  if
> > + (status != GRUB_EFI_SUCCESS)
> > +    return grub_efi_log_event_status (status);
> 
> I do not fully understand that. You return an error and later the return value
> from grub_cc_log_event() call is completely ignored.
> I think you should decide how to cope with errors first and ignore them in 
> this
> function. e.g. return void, or process errors from
> grub_cc_log_event() call in the caller accordingly.
[Lu, Ken] Thanks for this reminder! I will return void, since the error of 
grub_cc_log_event() should not block other TPM log event, because they can 
coexist.

> 
> > +  event = grub_zalloc (sizeof (grub_efi_cc_event_t)
> > +                  + grub_strlen (description) + 1);
> > +  if (event == NULL)
> > +    return grub_error (GRUB_ERR_OUT_OF_MEMORY,
> > +                  N_ ("cannot allocate CC event buffer"));
> 
> You do not need space after N_. Yeah, I know it is confusing but it is what 
> it is.
> Sorry...
[Lu, Ken] Thanks for this, I will fix it.

> 
> > +  event->Header.HeaderSize = sizeof (grub_efi_cc_event_header_t);
> > + event->Header.HeaderVersion = GRUB_EFI_CC_EVENT_HEADER_VERSION;
> > + event->Header.MrIndex = mr;  event->Header.EventType = EV_IPL;
> > + event->Size = sizeof (*event) - sizeof (event->Event)
> 
> You will not need '- sizeof (event->Event)' if you define Event[0], yes, 0 
> size,
> member in the grub_efi_cc_event_t.
[Lu, Ken] Very nice C programming tip, it will be more concise and readable. 
Could we keep this Event[1] now firstly aligning with UEFI's definition at 
https://github.com/tianocore/edk2/blob/d372ab585a2cdc5348af5f701c56c631235fe698/MdePkg/Include/Protocol/CcMeasurement.h#L100,
 I will talk with UEFI owner to make same changes in future.

> 
> > +           + grub_strlen (description) + 1;
> > +  grub_memcpy (event->Event, description, grub_strlen (description) +
> > +1);
> 
> I think grub_strcpy() would be more natural here. And you do not need copy 
> '\0'
> because grub_zalloc() did work for you earlier.
[Lu, Ken] Thanks for this comment, will fix it.

> 
> > +  status = efi_call_5 (cc->hash_log_extend_event, cc, 0,
> > +                  (grub_efi_physical_address_t) buf,
> > +                  (grub_efi_uint64_t) size, event);
> > +  grub_free (event);
> > +
> > +  return grub_efi_log_event_status (status); }
> > diff --git a/grub-core/commands/efi/tpm.c
> > b/grub-core/commands/efi/tpm.c index a97d85368..c40093fb4 100644
> > --- a/grub-core/commands/efi/tpm.c
> > +++ b/grub-core/commands/efi/tpm.c
> > @@ -22,6 +22,7 @@
> >  #include <grub/i18n.h>
> >  #include <grub/efi/api.h>
> >  #include <grub/efi/efi.h>
> > +#include <grub/efi/cc.h>
> >  #include <grub/efi/tpm.h>
> >  #include <grub/mm.h>
> >  #include <grub/tpm.h>
> > @@ -228,6 +229,8 @@ grub_tpm_measure (unsigned char *buf, grub_size_t
> size, grub_uint8_t pcr,
> >    grub_efi_handle_t tpm_handle;
> >    grub_efi_uint8_t protocol_version;
> >
> > +  grub_cc_log_event(buf, size, pcr, description);
> 
> ... and here you are ignoring return value...
> 
> Daniel
> 
> _______________________________________________
> Grub-devel mailing list
> Grub-devel@gnu.org
> https://lists.gnu.org/mailman/listinfo/grub-devel

reply via email to

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