All of lore.kernel.org
 help / color / mirror / Atom feed
From: Masahisa Kojima <masahisa.kojima@linaro.org>
To: Heinrich Schuchardt <xypron.glpk@gmx.de>
Cc: Ilias Apalodimas <ilias.apalodimas@linaro.org>,
	Alexander Graf <agraf@csgraf.de>,  Simon Glass <sjg@chromium.org>,
	U-Boot Mailing List <u-boot@lists.denx.de>
Subject: Re: [PATCH v3 2/3] efi_loader: add UEFI GPT measurement
Date: Mon, 4 Oct 2021 12:11:45 +0900	[thread overview]
Message-ID: <CADQ0-X90dt=1Y+8nR6uF3_sYgbKOrVGbKM9iNcfVN83a4COTRQ@mail.gmail.com> (raw)
In-Reply-To: <e012f597-0220-e0ad-89f8-9f528364800a@gmx.de>

On Sat, 2 Oct 2021 at 01:28, Heinrich Schuchardt <xypron.glpk@gmx.de> wrote:
>
>
>
> On 10/1/21 13:18, Masahisa Kojima wrote:
> > This commit adds the UEFI GPT disk partition topology
> > measurement required in TCG PC Client PFP Spec.
> >
> > Signed-off-by: Masahisa Kojima <masahisa.kojima@linaro.org>
> > ---
> >
> > Changes in v3:
> > - EV_EFI_GPT_EVENT is measured before EV_SEPARATOR, same as
> >    other PCRs
> > - use PTR_ARRAY instead of ARRAY
> > - create sub-function of allocating io_aligned buffer
> > - move search_gpt_dp_node() into efi_device_path.c
> >
> >   include/blk.h                    |   3 +
> >   include/efi_loader.h             |   3 +-
> >   include/efi_tcg2.h               |  12 +++
> >   lib/efi_loader/efi_boottime.c    |   2 +-
> >   lib/efi_loader/efi_device_path.c |  27 +++++
> >   lib/efi_loader/efi_tcg2.c        | 163 ++++++++++++++++++++++++++++++-
> >   6 files changed, 207 insertions(+), 3 deletions(-)
> >
> > diff --git a/include/blk.h b/include/blk.h
> > index 19bab081c2..f0cc7ca1a2 100644
> > --- a/include/blk.h
> > +++ b/include/blk.h
> > @@ -45,6 +45,9 @@ enum if_type {
> >   #define BLK_PRD_SIZE                20
> >   #define BLK_REV_SIZE                8
> >
> > +#define PART_FORMAT_PCAT     0x1
> > +#define PART_FORMAT_GPT              0x2
> > +
> >   /*
> >    * Identifies the partition table type (ie. MBR vs GPT GUID) signature
> >    */
> > diff --git a/include/efi_loader.h b/include/efi_loader.h
> > index 13f0c24058..c557e8bee6 100644
> > --- a/include/efi_loader.h
> > +++ b/include/efi_loader.h
> > @@ -503,7 +503,7 @@ efi_status_t efi_init_variables(void);
> >   void efi_variables_boot_exit_notify(void);
> >   efi_status_t efi_tcg2_notify_exit_boot_services_failed(void);
> >   /* Measure efi application invocation */
> > -efi_status_t efi_tcg2_measure_efi_app_invocation(void);
> > +efi_status_t efi_tcg2_measure_efi_app_invocation(struct efi_loaded_image_obj *handle);
> >   /* Measure efi application exit */
> >   efi_status_t efi_tcg2_measure_efi_app_exit(void);
> >   /* Called by bootefi to initialize root node */
> > @@ -845,6 +845,7 @@ struct efi_device_path *efi_dp_from_lo(struct efi_load_option *lo,
> >                                      efi_uintn_t *size, efi_guid_t guid);
> >   struct efi_device_path *efi_dp_concat(const struct efi_device_path *dp1,
> >                                     const struct efi_device_path *dp2);
> > +struct efi_device_path *search_gpt_dp_node(struct efi_device_path *device_path);
> >   efi_status_t efi_deserialize_load_option(struct efi_load_option *lo, u8 *data,
> >                                        efi_uintn_t *size);
> >   unsigned long efi_serialize_load_option(struct efi_load_option *lo, u8 **data);
> > diff --git a/include/efi_tcg2.h b/include/efi_tcg2.h
> > index ca66695b39..50a59f9263 100644
> > --- a/include/efi_tcg2.h
> > +++ b/include/efi_tcg2.h
> > @@ -225,6 +225,18 @@ struct smbios_handoff_table_pointers2 {
> >       struct efi_configuration_table table_entry[];
> >   } __packed;
> >
> > +/**
> > + * struct tdUEFI_GPT_DATA - event log structure of industry standard tables
> > + * @uefi_partition_header:   gpt partition header
> > + * @number_of_partitions:    the number of partition
> > + * @partitions:                      partition entries
> > + */
> > +struct efi_gpt_data {
> > +     gpt_header uefi_partition_header;
> > +     u64 number_of_partitions;
> > +     gpt_entry partitions[];
> > +} __packed;
> > +
> >   struct efi_tcg2_protocol {
> >       efi_status_t (EFIAPI * get_capability)(struct efi_tcg2_protocol *this,
> >                                              struct efi_tcg2_boot_service_capability *capability);
> > diff --git a/lib/efi_loader/efi_boottime.c b/lib/efi_loader/efi_boottime.c
> > index 701e2212c8..bf5661e1ee 100644
> > --- a/lib/efi_loader/efi_boottime.c
> > +++ b/lib/efi_loader/efi_boottime.c
> > @@ -3003,7 +3003,7 @@ efi_status_t EFIAPI efi_start_image(efi_handle_t image_handle,
> >
> >       if (IS_ENABLED(CONFIG_EFI_TCG2_PROTOCOL)) {
> >               if (image_obj->image_type == IMAGE_SUBSYSTEM_EFI_APPLICATION) {
> > -                     ret = efi_tcg2_measure_efi_app_invocation();
> > +                     ret = efi_tcg2_measure_efi_app_invocation(image_obj);
> >                       if (ret != EFI_SUCCESS) {
> >                               log_warning("tcg2 measurement fails(0x%lx)\n",
> >                                           ret);
> > diff --git a/lib/efi_loader/efi_device_path.c b/lib/efi_loader/efi_device_path.c
> > index cbdb466da4..6aec64f373 100644
> > --- a/lib/efi_loader/efi_device_path.c
> > +++ b/lib/efi_loader/efi_device_path.c
> > @@ -1294,3 +1294,30 @@ efi_device_path *efi_dp_from_lo(struct efi_load_option *lo,
> >
> >       return NULL;
> >   }
> > +
> > +/**
> > + * search_gpt_dp_node() - search gpt device path node
> > + *
> > + * @device_path:     device path
> > + *
> > + * Return:   pointer to the gpt device path node
> > + */
> > +struct efi_device_path *search_gpt_dp_node(struct efi_device_path *device_path)
>
> You are not adding the function to an include. So it should be static.

I added the function in efi_loader.h
---
diff --git a/include/efi_loader.h b/include/efi_loader.h
+struct efi_device_path *search_gpt_dp_node(struct efi_device_path
*device_path);
---

>
> > +{
> > +     struct efi_device_path *dp = device_path;
> > +
> > +     while (dp) {
> > +             if (dp->type == DEVICE_PATH_TYPE_MEDIA_DEVICE &&
> > +                 dp->sub_type == DEVICE_PATH_SUB_TYPE_HARD_DRIVE_PATH) {
> > +                     struct efi_device_path_hard_drive_path *hd_dp =
> > +                             (struct efi_device_path_hard_drive_path *)dp;
> > +
> > +                     if (hd_dp->partmap_type == PART_FORMAT_GPT &&
> > +                         hd_dp->signature_type == SIG_TYPE_GUID)
> > +                             return dp;
> > +             }
> > +             dp = efi_dp_next(dp);
> > +     }
> > +
> > +     return NULL;
> > +}
> > diff --git a/lib/efi_loader/efi_tcg2.c b/lib/efi_loader/efi_tcg2.c
> > index f14d4d6da1..28e0362bf2 100644
> > --- a/lib/efi_loader/efi_tcg2.c
> > +++ b/lib/efi_loader/efi_tcg2.c
> > @@ -1531,12 +1531,169 @@ static void *find_smbios_table(void)
> >       return NULL;
> >   }
> >
> > +static void *allocate_io_aligned_buf(void **buf, u32 size, u32 io_align)
> > +{
> Using memalign() avoids having two pointers and obsoletes this function.

Thank you, I will use memalign().

Regards,
Masahisa Kojima

>
> > +     if (!buf)
> > +             return NULL;
> > +
> > +     *buf = calloc(1, size);
>
> To create an aligned buffer with size bytes you would have to use size +
> io_align - 1.
>
> Best regards
>
> Heinrich
>
> > +     if (!*buf)
> > +             return NULL;
> > +
> > +     return (void *)PTR_ALIGN((uintptr_t)*buf, io_align);
> > +}
> > +
> > +/**
> > + * tcg2_measure_gpt_table() - measure gpt table
> > + *
> > + * @dev:             TPM device
> > + * @loaded_image:    handle to the loaded image
> > + *
> > + * Return:   status code
> > + */
> > +static efi_status_t
> > +tcg2_measure_gpt_data(struct udevice *dev,
> > +                   struct efi_loaded_image_obj *loaded_image)
> > +{
> > +     efi_status_t ret;
> > +     efi_handle_t handle;
> > +     struct efi_handler *dp_handler;
> > +     struct efi_device_path *orig_device_path;
> > +     struct efi_device_path *device_path;
> > +     struct efi_device_path *dp;
> > +     struct efi_block_io *block_io;
> > +     struct efi_gpt_data *event = NULL;
> > +     efi_guid_t null_guid = NULL_GUID;
> > +     void *orig_gpt_h = NULL;
> > +     void *orig_gpt_e = NULL;
> > +     gpt_header *gpt_h = NULL;
> > +     gpt_entry *entry = NULL;
> > +     gpt_entry *gpt_e;
> > +     u32 num_of_valid_entry = 0;
> > +     u32 event_size;
> > +     u32 i;
> > +     u32 total_gpt_entry_size;
> > +
> > +     ret = efi_search_protocol(&loaded_image->header,
> > +                               &efi_guid_loaded_image_device_path,
> > +                               &dp_handler);
> > +     if (ret != EFI_SUCCESS)
> > +             return ret;
> > +
> > +     orig_device_path = dp_handler->protocol_interface;
> > +     device_path = efi_dp_dup(orig_device_path);
> > +     if (!device_path)
> > +             return EFI_OUT_OF_RESOURCES;
> > +
> > +     dp = search_gpt_dp_node(device_path);
> > +     if (!dp) {
> > +             /* no GPT device path node found, skip GPT measurement */
> > +             ret = EFI_SUCCESS;
> > +             goto out1;
> > +     }
> > +
> > +     /* read GPT header */
> > +     dp->type = DEVICE_PATH_TYPE_END;
> > +     dp->sub_type = DEVICE_PATH_SUB_TYPE_END;
> > +     dp = device_path;
> > +     ret = EFI_CALL(systab.boottime->locate_device_path(&efi_block_io_guid,
> > +                                                        &dp, &handle));
> > +     if (ret != EFI_SUCCESS)
> > +             goto out1;
> > +
> > +     ret = EFI_CALL(efi_handle_protocol(handle,
> > +                                        &efi_block_io_guid, (void **)&block_io));
> > +     if (ret != EFI_SUCCESS)
> > +             goto out1;
> > +
> > +     gpt_h = allocate_io_aligned_buf(&orig_gpt_h,
> > +                                     block_io->media->block_size +
> > +                                     block_io->media->io_align,
> > +                                     block_io->media->io_align);
> > +     if (!orig_gpt_h || !gpt_h) {
> > +             ret = EFI_OUT_OF_RESOURCES;
> > +             goto out2;
> > +     }
> > +
> > +     ret = block_io->read_blocks(block_io, block_io->media->media_id, 1,
> > +                                 block_io->media->block_size, gpt_h);
> > +     if (ret != EFI_SUCCESS)
> > +             goto out2;
> > +
> > +     /* read GPT entry */
> > +     total_gpt_entry_size = gpt_h->num_partition_entries *
> > +                            gpt_h->sizeof_partition_entry;
> > +     entry = allocate_io_aligned_buf(&orig_gpt_e,
> > +                                     total_gpt_entry_size +
> > +                                     block_io->media->io_align,
> > +                                     block_io->media->io_align);
> > +     if (!orig_gpt_e || !entry) {
> > +             ret = EFI_OUT_OF_RESOURCES;
> > +             goto out2;
> > +     }
> > +
> > +     ret = block_io->read_blocks(block_io, block_io->media->media_id,
> > +                                 gpt_h->partition_entry_lba,
> > +                                 total_gpt_entry_size, entry);
> > +     if (ret != EFI_SUCCESS)
> > +             goto out2;
> > +
> > +     /* count valid GPT entry */
> > +     gpt_e = entry;
> > +     for (i = 0; i < gpt_h->num_partition_entries; i++) {
> > +             if (guidcmp(&null_guid, &gpt_e->partition_type_guid))
> > +                     num_of_valid_entry++;
> > +
> > +             gpt_e = (gpt_entry *)((u8 *)gpt_e + gpt_h->sizeof_partition_entry);
> > +     }
> > +
> > +     /* prepare event data for measurement */
> > +     event_size = sizeof(struct efi_gpt_data) +
> > +             (num_of_valid_entry * gpt_h->sizeof_partition_entry);
> > +     event = calloc(1, event_size);
> > +     if (!event) {
> > +             ret = EFI_OUT_OF_RESOURCES;
> > +             goto out2;
> > +     }
> > +     memcpy(event, gpt_h, sizeof(gpt_header));
> > +     put_unaligned_le64(num_of_valid_entry, &event->number_of_partitions);
> > +
> > +     /* copy valid GPT entry */
> > +     gpt_e = entry;
> > +     num_of_valid_entry = 0;
> > +     for (i = 0; i < gpt_h->num_partition_entries; i++) {
> > +             if (guidcmp(&null_guid, &gpt_e->partition_type_guid)) {
> > +                     memcpy((u8 *)event->partitions +
> > +                            (num_of_valid_entry * gpt_h->sizeof_partition_entry),
> > +                            gpt_e, gpt_h->sizeof_partition_entry);
> > +                     num_of_valid_entry++;
> > +             }
> > +
> > +             gpt_e = (gpt_entry *)((u8 *)gpt_e + gpt_h->sizeof_partition_entry);
> > +     }
> > +
> > +     ret = tcg2_measure_event(dev, 5, EV_EFI_GPT_EVENT, event_size, (u8 *)event);
> > +     if (ret != EFI_SUCCESS)
> > +             goto out2;
> > +
> > +out2:
> > +     EFI_CALL(efi_close_protocol((efi_handle_t)block_io, &efi_block_io_guid,
> > +                                 NULL, NULL));
> > +     free(orig_gpt_h);
> > +     free(orig_gpt_e);
> > +     free(event);
> > +out1:
> > +     efi_free_pool(device_path);
> > +
> > +     return ret;
> > +}
> > +
> >   /**
> >    * efi_tcg2_measure_efi_app_invocation() - measure efi app invocation
> >    *
> >    * Return:  status code
> >    */
> > -efi_status_t efi_tcg2_measure_efi_app_invocation(void)
> > +efi_status_t efi_tcg2_measure_efi_app_invocation(struct efi_loaded_image_obj *handle)
> >   {
> >       efi_status_t ret;
> >       u32 pcr_index;
> > @@ -1568,6 +1725,10 @@ efi_status_t efi_tcg2_measure_efi_app_invocation(void)
> >                       goto out;
> >       }
> >
> > +     ret = tcg2_measure_gpt_data(dev, handle);
> > +     if (ret != EFI_SUCCESS)
> > +             goto out;
> > +
> >       for (pcr_index = 0; pcr_index <= 7; pcr_index++) {
> >               ret = tcg2_measure_event(dev, pcr_index, EV_SEPARATOR,
> >                                        sizeof(event), (u8 *)&event);
> >

  reply	other threads:[~2021-10-04  3:12 UTC|newest]

Thread overview: 21+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-10-01 11:18 [PATCH v3 0/3] Enhance Measured Boot Masahisa Kojima
2021-10-01 11:18 ` [PATCH v3 1/3] efi_loader: add SMBIOS table measurement Masahisa Kojima
2021-10-01 15:23   ` Simon Glass
2021-10-01 19:47     ` Ilias Apalodimas
2021-10-21  0:12   ` Heinrich Schuchardt
2021-10-21  8:38     ` Masahisa Kojima
2021-10-21  8:49       ` Heinrich Schuchardt
2021-10-21 12:52         ` Masahisa Kojima
2021-10-21 12:59           ` Heinrich Schuchardt
2021-10-21 13:41             ` Masahisa Kojima
2021-11-02 14:56               ` Simon Glass
2021-11-04  1:26                 ` Masahisa Kojima
2021-10-01 11:18 ` [PATCH v3 2/3] efi_loader: add UEFI GPT measurement Masahisa Kojima
2021-10-01 15:23   ` Simon Glass
2021-10-22 10:49     ` Masahisa Kojima
2021-10-01 16:28   ` Heinrich Schuchardt
2021-10-04  3:11     ` Masahisa Kojima [this message]
2021-10-01 11:18 ` [PATCH v3 3/3] efi_loader: add DeployedMode and AuditMode variable measurement Masahisa Kojima
2021-10-01 16:43   ` Heinrich Schuchardt
2021-10-04  2:30     ` Masahisa Kojima
2021-10-22  8:04       ` Masahisa Kojima

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to='CADQ0-X90dt=1Y+8nR6uF3_sYgbKOrVGbKM9iNcfVN83a4COTRQ@mail.gmail.com' \
    --to=masahisa.kojima@linaro.org \
    --cc=agraf@csgraf.de \
    --cc=ilias.apalodimas@linaro.org \
    --cc=sjg@chromium.org \
    --cc=u-boot@lists.denx.de \
    --cc=xypron.glpk@gmx.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.