All of lore.kernel.org
 help / color / mirror / Atom feed
From: AKASHI Takahiro <takahiro.akashi@linaro.org>
To: Heinrich Schuchardt <xypron.glpk@gmx.de>
Cc: Masahisa Kojima <masahisa.kojima@linaro.org>,
	Alexander Graf <agraf@csgraf.de>,
	Ilias Apalodimas <ilias.apalodimas@linaro.org>,
	Simon Glass <sjg@chromium.org>,
	Dhananjay Phadke <dphadke@linux.microsoft.com>,
	U-Boot Mailing List <u-boot@lists.denx.de>
Subject: Re: [PATCH 3/5] efi_loader: add boot variable measurement
Date: Wed, 14 Jul 2021 08:54:10 +0900	[thread overview]
Message-ID: <20210713235410.GA41906@laputa> (raw)
In-Reply-To: <6b8a8baa-49a1-ca55-6f01-340ee591b79c@gmx.de>

On Tue, Jul 13, 2021 at 04:24:52PM +0200, Heinrich Schuchardt wrote:
> 
> 
> On 13.07.21 10:31, Masahisa Kojima wrote:
> > Hi Heinrich,
> > 
> > > > > TCG spec also requires to measure "Calling EFI Application from
> > > > > Boot Option" for each boot attempt, and "Returning from EFI
> > > > > Application from Boot Option" if a boot device returns control
> > > > > back to the Boot Manager.
> > 
> > I would like to hear your opinion regarding
> > "Calling EFI Application from Boot Option" measurement.
> > 
> > My current(v1 patch series) implementation considers
> > both "bootefi bootmgr" and "bootefi $image_addr" cases,
> > so I do this "Calling EFI Application from Boot Option" measurement
> > at efi_boottime.c::efi_start_image().
> > Do I need to implement only the case UEFI application boot from bootmgr?
> > If yes, I will move the timing of this measurement at
> > efi_bootmgr.c::efi_bootmgr_load().
> > 
> > As a reference, in edk2, this measurement is performed in
> > ready_to_boot event handler, ready_to_boot handler is called
> > upon the user selects the boot option in boot manager.
> 
> When booting you can call
> 
>    bootefi $driver1
>    booefii $driver2
>    bootefi bootmgr
> 
> in sequence.
> 
> Any of the binaries can call LoadImage(), StartImage() multiple times to
> execute further images. E.g. I am loading iPXE. By default it loads GRUB
> from an iSCSI drive but I can choose in the menu or the iPXE console to
> invoke another UEFI binary.
> 
> I suggest to measure any image no matter how it is invoked. The
> measurement must depend on the sequence of invocation.

Moreover,
booting from the default path, like /EFI/BOOT/BOOTAA64.EFI,
is only implemented by using bootefi <addr> syntax.

-Takahiro Akashi


> Best regards
> 
> Heinrich
> 
> > 
> > What do you think?
> > 
> > Thanks,
> > Masahisa Kojima
> > 
> > 
> > 
> > 
> > 
> > On Fri, 9 Jul 2021 at 11:44, Masahisa Kojima <masahisa.kojima@linaro.org> wrote:
> > > 
> > > On Fri, 9 Jul 2021 at 02:46, Heinrich Schuchardt <xypron.glpk@gmx.de> wrote:
> > > > 
> > > > On 7/7/21 3:36 PM, Masahisa Kojima wrote:
> > > > > TCG PC Client PFP spec requires to measure "Boot####"
> > > > > and "BootOrder" variables, EV_SEPARATOR event prior
> > > > > to the Ready to Boot invocation.
> > > > > Since u-boot does not implement Ready to Boot event,
> > > > > these measurements are performed when efi_start_image() is called.
> > > > > 
> > > > > TCG spec also requires to measure "Calling EFI Application from
> > > > > Boot Option" for each boot attempt, and "Returning from EFI
> > > > > Application from Boot Option" if a boot device returns control
> > > > > back to the Boot Manager.
> > > > > 
> > > > > Signed-off-by: Masahisa Kojima <masahisa.kojima@linaro.org>
> > > > > ---
> > > > >    include/efi_loader.h          |   4 ++
> > > > >    include/tpm-v2.h              |  18 ++++-
> > > > >    lib/efi_loader/efi_boottime.c |  20 ++++++
> > > > >    lib/efi_loader/efi_tcg2.c     | 123 ++++++++++++++++++++++++++++++++++
> > > > >    4 files changed, 164 insertions(+), 1 deletion(-)
> > > > > 
> > > > > diff --git a/include/efi_loader.h b/include/efi_loader.h
> > > > > index 0a9c82a257..281ffff30f 100644
> > > > > --- a/include/efi_loader.h
> > > > > +++ b/include/efi_loader.h
> > > > > @@ -407,6 +407,10 @@ efi_status_t efi_run_image(void *source_buffer, efi_uintn_t source_size);
> > > > >    efi_status_t efi_init_variables(void);
> > > > >    /* Notify ExitBootServices() is called */
> > > > >    void efi_variables_boot_exit_notify(void);
> > > > > +/* Measure efi application invocation */
> > > > > +efi_status_t EFIAPI efi_tcg2_measure_efi_app_invocation(void);
> > > > > +/* Measure efi application exit */
> > > > > +efi_status_t EFIAPI efi_tcg2_measure_efi_app_exit(void);
> > > > >    /* Called by bootefi to initialize root node */
> > > > >    efi_status_t efi_root_node_register(void);
> > > > >    /* Called by bootefi to initialize runtime */
> > > > > diff --git a/include/tpm-v2.h b/include/tpm-v2.h
> > > > > index 3e48e35861..8a7b7f1874 100644
> > > > > --- a/include/tpm-v2.h
> > > > > +++ b/include/tpm-v2.h
> > > > > @@ -73,7 +73,7 @@ struct udevice;
> > > > >    /*
> > > > >     * event types, cf.
> > > > >     * "TCG PC Client Platform Firmware Profile Specification", Family "2.0"
> > > > > - * rev 1.04, June 3, 2019
> > > > > + * Level 00 Version 1.05 Revision 23, May 7, 2021
> > > > >     */
> > > > >    #define EV_EFI_EVENT_BASE                   ((u32)0x80000000)
> > > > >    #define EV_EFI_VARIABLE_DRIVER_CONFIG               ((u32)0x80000001)
> > > > > @@ -85,8 +85,24 @@ struct udevice;
> > > > >    #define EV_EFI_ACTION                               ((u32)0x80000007)
> > > > >    #define EV_EFI_PLATFORM_FIRMWARE_BLOB               ((u32)0x80000008)
> > > > >    #define EV_EFI_HANDOFF_TABLES                       ((u32)0x80000009)
> > > > > +#define EV_EFI_PLATFORM_FIRMWARE_BLOB2               ((u32)0x8000000A)
> > > > > +#define EV_EFI_HANDOFF_TABLES2                       ((u32)0x8000000B)
> > > > > +#define EV_EFI_VARIABLE_BOOT2                        ((u32)0x8000000C)
> > > > >    #define EV_EFI_HCRTM_EVENT                  ((u32)0x80000010)
> > > > >    #define EV_EFI_VARIABLE_AUTHORITY           ((u32)0x800000E0)
> > > > > +#define EV_EFI_SPDM_FIRMWARE_BLOB            ((u32)0x800000E1)
> > > > > +#define EV_EFI_SPDM_FIRMWARE_CONFIG          ((u32)0x800000E2)
> > > > > +
> > > > > +#define EFI_CALLING_EFI_APPLICATION         \
> > > > > +     "Calling EFI Application from Boot Option"
> > > > > +#define EFI_RETURNING_FROM_EFI_APPLICATION  \
> > > > > +     "Returning from EFI Application from Boot Option"
> > > > > +#define EFI_EXIT_BOOT_SERVICES_INVOCATION   \
> > > > > +     "Exit Boot Services Invocation"
> > > > > +#define EFI_EXIT_BOOT_SERVICES_FAILED       \
> > > > > +     "Exit Boot Services Returned with Failure"
> > > > > +#define EFI_EXIT_BOOT_SERVICES_SUCCEEDED    \
> > > > > +     "Exit Boot Services Returned with Success"
> > > > 
> > > > Which spec defines if the string in the event log shall be utf-8 or utf-16?
> > > 
> > > TCG PC Client PFP spec does not clearly define the character encoding.
> > > In my understanding, the string derived from UEFI spec such as
> > > UEFI variable name uses utf-16(CHAR16).
> > > Other strings like "Calling EFI Application from Boot Option" defind in TCG PC
> > > Client spec use 1 byte ASCII encoding.
> > > 
> > > EDK2 implementation also uses 1 byte ASCII encoding for these strings,
> > > and tpm2-tools::tpm2_eventlog command can handles properly.
> > > 
> > > Thanks,
> > > Masahisa Kojima
> > > 
> > > > 
> > > > Best regards
> > > > 
> > > > Heinrich
> > > > 
> > > > > 
> > > > >    /* TPMS_TAGGED_PROPERTY Structure */
> > > > >    struct tpms_tagged_property {
> > > > > diff --git a/lib/efi_loader/efi_boottime.c b/lib/efi_loader/efi_boottime.c
> > > > > index f6d5ba05e3..2914800c56 100644
> > > > > --- a/lib/efi_loader/efi_boottime.c
> > > > > +++ b/lib/efi_loader/efi_boottime.c
> > > > > @@ -2993,6 +2993,16 @@ efi_status_t EFIAPI efi_start_image(efi_handle_t image_handle,
> > > > >        image_obj->exit_status = &exit_status;
> > > > >        image_obj->exit_jmp = &exit_jmp;
> > > > > 
> > > > > +     if (IS_ENABLED(CONFIG_EFI_TCG2_PROTOCOL)) {
> > > > > +             if (image_obj->image_type == IMAGE_SUBSYSTEM_EFI_APPLICATION) {
> > > > > +                     ret = efi_tcg2_measure_efi_app_invocation();
> > > > > +                     if (ret != EFI_SUCCESS) {
> > > > > +                             EFI_PRINT("tcg2 measurement fails(0x%lx)\n",
> > > > > +                                       ret);
> > > > > +                     }
> > > > > +             }
> > > > > +     }
> > > > > +
> > > > >        /* call the image! */
> > > > >        if (setjmp(&exit_jmp)) {
> > > > >                /*
> > > > > @@ -3251,6 +3261,16 @@ static efi_status_t EFIAPI efi_exit(efi_handle_t image_handle,
> > > > >            exit_status != EFI_SUCCESS)
> > > > >                efi_delete_image(image_obj, loaded_image_protocol);
> > > > > 
> > > > > +     if (IS_ENABLED(CONFIG_EFI_TCG2_PROTOCOL)) {
> > > > > +             if (image_obj->image_type == IMAGE_SUBSYSTEM_EFI_APPLICATION) {
> > > > > +                     ret = efi_tcg2_measure_efi_app_exit();
> > > > > +                     if (ret != EFI_SUCCESS) {
> > > > > +                             EFI_PRINT("tcg2 measurement fails(0x%lx)\n",
> > > > > +                                       ret);
> > > > > +                     }
> > > > > +             }
> > > > > +     }
> > > > > +
> > > > >        /* Make sure entry/exit counts for EFI world cross-overs match */
> > > > >        EFI_EXIT(exit_status);
> > > > > 
> > > > > diff --git a/lib/efi_loader/efi_tcg2.c b/lib/efi_loader/efi_tcg2.c
> > > > > index 2a248bd62a..6e903e3cb3 100644
> > > > > --- a/lib/efi_loader/efi_tcg2.c
> > > > > +++ b/lib/efi_loader/efi_tcg2.c
> > > > > @@ -35,6 +35,7 @@ struct event_log_buffer {
> > > > >    };
> > > > > 
> > > > >    static struct event_log_buffer event_log;
> > > > > +static bool tcg2_efi_app_invoked;
> > > > >    /*
> > > > >     * When requesting TPM2_CAP_TPM_PROPERTIES the value is on a standard offset.
> > > > >     * Since the current tpm2_get_capability() response buffers starts at
> > > > > @@ -1383,6 +1384,128 @@ static efi_status_t tcg2_measure_variable(struct udevice *dev, u32 pcr_index,
> > > > >        return ret;
> > > > >    }
> > > > > 
> > > > > +/**
> > > > > + * tcg2_measure_boot_variable() - measure boot variables
> > > > > + *
> > > > > + * @dev:     TPM device
> > > > > + *
> > > > > + * Return:   status code
> > > > > + */
> > > > > +static efi_status_t tcg2_measure_boot_variable(struct udevice *dev)
> > > > > +{
> > > > > +     u16 *boot_order;
> > > > > +     u16 var_name[] = L"BootOrder";
> > > > > +     u16 boot_name[] = L"Boot0000";
> > > > > +     u16 hexmap[] = L"0123456789ABCDEF";
> > > > > +     u8 *bootvar;
> > > > > +     efi_uintn_t var_data_size;
> > > > > +     u32 count, i;
> > > > > +     efi_status_t ret;
> > > > > +
> > > > > +     boot_order = efi_get_var(var_name, &efi_global_variable_guid,
> > > > > +                              &var_data_size);
> > > > > +     if (!boot_order) {
> > > > > +             log_info("BootOrder not defined\n");
> > > > > +             ret = EFI_NOT_FOUND;
> > > > > +             goto error;
> > > > > +     }
> > > > > +
> > > > > +     ret = tcg2_measure_variable(dev, 1, EV_EFI_VARIABLE_BOOT2, var_name,
> > > > > +                                 &efi_global_variable_guid, var_data_size,
> > > > > +                                 (u8 *)boot_order);
> > > > > +     if (ret != EFI_SUCCESS)
> > > > > +             goto error;
> > > > > +
> > > > > +     count = var_data_size / sizeof(*boot_order);
> > > > > +     for (i = 0; i < count; i++) {
> > > > > +             boot_name[4] = hexmap[(boot_order[i] & 0xf000) >> 12];
> > > > > +             boot_name[5] = hexmap[(boot_order[i] & 0x0f00) >> 8];
> > > > > +             boot_name[6] = hexmap[(boot_order[i] & 0x00f0) >> 4];
> > > > > +             boot_name[7] = hexmap[(boot_order[i] & 0x000f)];
> > > > > +
> > > > > +             bootvar = efi_get_var(boot_name, &efi_global_variable_guid,
> > > > > +                                   &var_data_size);
> > > > > +
> > > > > +             if (!bootvar) {
> > > > > +                     log_info("%ls not found\n", boot_name);
> > > > > +                     continue;
> > > > > +             }
> > > > > +
> > > > > +             ret = tcg2_measure_variable(dev, 1, EV_EFI_VARIABLE_BOOT2,
> > > > > +                                         boot_name,
> > > > > +                                         &efi_global_variable_guid,
> > > > > +                                         var_data_size, bootvar);
> > > > > +             free(bootvar);
> > > > > +             if (ret != EFI_SUCCESS)
> > > > > +                     goto error;
> > > > > +     }
> > > > > +
> > > > > +error:
> > > > > +     free(boot_order);
> > > > > +     return ret;
> > > > > +}
> > > > > +
> > > > > +/**
> > > > > + * efi_tcg2_measure_efi_app_invocation() - measure efi app invocation
> > > > > + *
> > > > > + * Return:   status code
> > > > > + */
> > > > > +efi_status_t EFIAPI efi_tcg2_measure_efi_app_invocation(void)
> > > > > +{
> > > > > +     efi_status_t ret;
> > > > > +     u32 pcr_index;
> > > > > +     struct udevice *dev;
> > > > > +     u32 event = 0;
> > > > > +
> > > > > +     if (tcg2_efi_app_invoked)
> > > > > +             return EFI_SUCCESS;
> > > > > +
> > > > > +     ret = platform_get_tpm2_device(&dev);
> > > > > +     if (ret != EFI_SUCCESS)
> > > > > +             return ret;
> > > > > +
> > > > > +     ret = tcg2_measure_boot_variable(dev);
> > > > > +     if (ret != EFI_SUCCESS)
> > > > > +             goto out;
> > > > > +
> > > > > +     ret = tcg2_measure_event(dev, 4, EV_EFI_ACTION,
> > > > > +                              strlen(EFI_CALLING_EFI_APPLICATION),
> > > > > +                              (u8 *)EFI_CALLING_EFI_APPLICATION);
> > > > > +     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);
> > > > > +             if (ret != EFI_SUCCESS)
> > > > > +                     goto out;
> > > > > +     }
> > > > > +
> > > > > +     tcg2_efi_app_invoked = true;
> > > > > +out:
> > > > > +     return ret;
> > > > > +}
> > > > > +
> > > > > +/**
> > > > > + * efi_tcg2_measure_efi_app_exit() - measure efi app exit
> > > > > + *
> > > > > + * Return:   status code
> > > > > + */
> > > > > +efi_status_t EFIAPI efi_tcg2_measure_efi_app_exit(void)
> > > > > +{
> > > > > +     efi_status_t ret;
> > > > > +     struct udevice *dev;
> > > > > +
> > > > > +     ret = platform_get_tpm2_device(&dev);
> > > > > +     if (ret != EFI_SUCCESS)
> > > > > +             return ret;
> > > > > +
> > > > > +     ret = tcg2_measure_event(dev, 4, EV_EFI_ACTION,
> > > > > +                              strlen(EFI_RETURNING_FROM_EFI_APPLICATION),
> > > > > +                              (u8 *)EFI_RETURNING_FROM_EFI_APPLICATION);
> > > > > +     return ret;
> > > > > +}
> > > > > +
> > > > >    /**
> > > > >     * tcg2_measure_secure_boot_variable() - measure secure boot variables
> > > > >     *
> > > > > 
> > > > 

  reply	other threads:[~2021-07-13 23:54 UTC|newest]

Thread overview: 40+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-07-07 13:36 [PATCH 0/5] add measurement support Masahisa Kojima
2021-07-07 13:36 ` [PATCH 1/5] efi_loader: increase eventlog buffer size Masahisa Kojima
2021-07-07 13:47   ` Heinrich Schuchardt
2021-07-08  2:21     ` Masahisa Kojima
2021-07-11  0:01       ` Simon Glass
2021-07-12  8:40         ` Masahisa Kojima
2021-07-12  9:27           ` Ilias Apalodimas
2021-07-14 14:52             ` Simon Glass
2021-07-15  6:20               ` Ilias Apalodimas
2021-07-15 12:57                 ` Simon Glass
2021-07-15 14:33                   ` Heinrich Schuchardt
2021-07-15 15:18                     ` Simon Glass
2021-07-15 15:29                       ` Heinrich Schuchardt
2021-07-15 16:09                         ` Simon Glass
2021-07-14 14:50           ` Simon Glass
2021-07-15  5:09             ` Masahisa Kojima
2021-07-15  6:46               ` Ilias Apalodimas
2021-07-15  7:50                 ` Masahisa Kojima
2021-07-07 13:36 ` [PATCH 2/5] efi_loader: add secure boot variable measurement Masahisa Kojima
2021-07-07 17:37   ` Simon Glass
2021-07-07 17:40     ` Ilias Apalodimas
2021-07-07 17:49       ` Simon Glass
2021-07-07 18:44         ` Ilias Apalodimas
2021-07-08 17:46   ` Heinrich Schuchardt
2021-07-09  2:34     ` Masahisa Kojima
2021-07-07 13:36 ` [PATCH 3/5] efi_loader: add " Masahisa Kojima
2021-07-07 18:56   ` Ilias Apalodimas
2021-07-08  2:44     ` Masahisa Kojima
2021-07-08 17:46   ` Heinrich Schuchardt
2021-07-09  2:44     ` Masahisa Kojima
2021-07-13  8:31       ` Masahisa Kojima
2021-07-13 14:24         ` Heinrich Schuchardt
2021-07-13 23:54           ` AKASHI Takahiro [this message]
2021-07-14  0:40             ` Masahisa Kojima
2021-07-07 13:36 ` [PATCH 4/5] efi_loader: add ExitBootServices() measurement Masahisa Kojima
2021-07-08 17:40   ` Heinrich Schuchardt
2021-07-09  3:05     ` Masahisa Kojima
2021-07-07 13:36 ` [PATCH 5/5] efi_loader: refactor efi_append_scrtm_version() Masahisa Kojima
2021-07-08 17:31   ` Heinrich Schuchardt
2021-07-09  2:05     ` 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=20210713235410.GA41906@laputa \
    --to=takahiro.akashi@linaro.org \
    --cc=agraf@csgraf.de \
    --cc=dphadke@linux.microsoft.com \
    --cc=ilias.apalodimas@linaro.org \
    --cc=masahisa.kojima@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.