Re: [PATCH v8 3/3] efi_loader: add PE/COFF image measurement

2021-05-25 Thread Masahisa Kojima
Hi Heinrich,

> > > + /*
> > > +  * Size must be 8-byte aligned and the trailing bytes must be
> > > +  * zero'ed. Otherwise hash value may be incorrect.
> > > +  */
> > > + if (!IS_ALIGNED(*efi_size, 8)) {
> >
> > Why don't you unconditionally copy to a new buffer? Then the caller can
> > free the return value unconditionally.

I sent out v9 just now. I don't include unconditionally copy to a new buffer,
because new version increases the readability I think.
If you still prefer to copy, I will do so.

Thanks,
Masahisa Kojima


On Tue, 25 May 2021 at 22:47, Masahisa Kojima
 wrote:
>
> On Tue, 25 May 2021 at 21:57, Heinrich Schuchardt  wrote:
> >
> > On 14.05.21 02:53, Masahisa Kojima wrote:
> > > "TCG PC Client Platform Firmware Profile Specification"
> > > requires to measure every attempt to load and execute
> > > a OS Loader(a UEFI application) into PCR[4].
> > > This commit adds the PE/COFF image measurement, extends PCR,
> > > and appends measurement into Event Log.
> > >
> > > Acked-by: Ilias Apalodimas 
> > > Tested-by: Ilias Apalodimas 
> > > Signed-off-by: Masahisa Kojima 
> > > ---
> > >
> > > (no changes since v7)
> > >
> > > Changes in v7:
> > > - include hash-checksum.h instead of rsa.h
> > > - select HASH_CALCULATE in Kconfig, not to update lib/Makefile
> > > - rebased the base code
> > >
> > > Changes in v6:
> > > - update lib/Makefile to add hash-checksum.c as a compilation target
> > >
> > > (no changes since v2)
> > >
> > > Changes in v2:
> > > - Remove duplicate  include
> > > - Remove unnecessary __packed attribute
> > > - Add all EV_EFI_* event definition
> > > - Create common function to prepare 8-byte aligned image
> > > - Add measurement for EV_EFI_BOOT_SERVICES_DRIVER and
> > >   EV_EFI_RUNTIME_SERVICES_DRIVER
> > > - Use efi_search_protocol() to get device_path
> > > - Add function comment
> > >
> > >  include/efi_loader.h  |   6 +
> > >  include/efi_tcg2.h|   9 ++
> > >  include/tpm-v2.h  |  18 +++
> > >  lib/efi_loader/Kconfig|   1 +
> > >  lib/efi_loader/efi_image_loader.c |  59 +++--
> > >  lib/efi_loader/efi_tcg2.c | 207 --
> > >  6 files changed, 276 insertions(+), 24 deletions(-)
> > >
> > > diff --git a/include/efi_loader.h b/include/efi_loader.h
> > > index de1a496a97..9f2854a255 100644
> > > --- a/include/efi_loader.h
> > > +++ b/include/efi_loader.h
> > > @@ -426,6 +426,10 @@ efi_status_t efi_disk_register(void);
> > >  efi_status_t efi_rng_register(void);
> > >  /* Called by efi_init_obj_list() to install EFI_TCG2_PROTOCOL */
> > >  efi_status_t efi_tcg2_register(void);
> > > +/* measure the pe-coff image, extend PCR and add Event Log */
> > > +efi_status_t tcg2_measure_pe_image(void *efi, u64 efi_size,
> > > +struct efi_loaded_image_obj *handle,
> > > +struct efi_loaded_image 
> > > *loaded_image_info);
> > >  /* Create handles and protocols for the partitions of a block device */
> > >  int efi_disk_create_partitions(efi_handle_t parent, struct blk_desc 
> > > *desc,
> > >  const char *if_typename, int diskid,
> > > @@ -847,6 +851,8 @@ bool efi_secure_boot_enabled(void);
> > >
> > >  bool efi_capsule_auth_enabled(void);
> > >
> > > +void *efi_prepare_aligned_image(void *efi, u64 *efi_size, void 
> > > **new_efi);
> > > +
> > >  bool efi_image_parse(void *efi, size_t len, struct efi_image_regions 
> > > **regp,
> > >WIN_CERTIFICATE **auth, size_t *auth_len);
> > >
> > > diff --git a/include/efi_tcg2.h b/include/efi_tcg2.h
> > > index 40e241ce31..bcfb98168a 100644
> > > --- a/include/efi_tcg2.h
> > > +++ b/include/efi_tcg2.h
> > > @@ -9,6 +9,7 @@
> > >  #if !defined _EFI_TCG2_PROTOCOL_H_
> > >  #define _EFI_TCG2_PROTOCOL_H_
> > >
> > > +#include 
> > >  #include 
> > >
> > >  #define EFI_TCG2_PROTOCOL_GUID \
> > > @@ -53,6 +54,14 @@ struct efi_tcg2_event {
> > >   u8 event[];
> > >  } __packed;
> > >
> > > +struct uefi_image_load_event {
> > > + efi_physical_addr_t image_location_in_memory;
> > > + u64 image_length_in_memory;
> > > + u64 image_link_time_address;
> > > + u64 length_of_device_path;
> > > + struct efi_device_path device_path[];
> > > +};
> > > +
> > >  struct efi_tcg2_boot_service_capability {
> > >   u8 size;
> > >   struct efi_tcg2_version structure_version;
> > > diff --git a/include/tpm-v2.h b/include/tpm-v2.h
> > > index 7de7d6a57d..247b386967 100644
> > > --- a/include/tpm-v2.h
> > > +++ b/include/tpm-v2.h
> > > @@ -70,6 +70,24 @@ struct udevice;
> > >  #define EV_TABLE_OF_DEVICES  ((u32)0x000B)
> > >  #define EV_COMPACT_HASH  ((u32)0x000C)
> > >
> > > +/*
> > > + * event types, cf.
> > > + * "TCG PC Client Platform Firmware Profile Specification", Family "2.0"
> > > + * rev 1.04, June 3, 2019
> > > + */
> > > +#define EV_EFI_EVENT_BASE((u

Re: [PATCH v8 3/3] efi_loader: add PE/COFF image measurement

2021-05-25 Thread Masahisa Kojima
On Tue, 25 May 2021 at 21:57, Heinrich Schuchardt  wrote:
>
> On 14.05.21 02:53, Masahisa Kojima wrote:
> > "TCG PC Client Platform Firmware Profile Specification"
> > requires to measure every attempt to load and execute
> > a OS Loader(a UEFI application) into PCR[4].
> > This commit adds the PE/COFF image measurement, extends PCR,
> > and appends measurement into Event Log.
> >
> > Acked-by: Ilias Apalodimas 
> > Tested-by: Ilias Apalodimas 
> > Signed-off-by: Masahisa Kojima 
> > ---
> >
> > (no changes since v7)
> >
> > Changes in v7:
> > - include hash-checksum.h instead of rsa.h
> > - select HASH_CALCULATE in Kconfig, not to update lib/Makefile
> > - rebased the base code
> >
> > Changes in v6:
> > - update lib/Makefile to add hash-checksum.c as a compilation target
> >
> > (no changes since v2)
> >
> > Changes in v2:
> > - Remove duplicate  include
> > - Remove unnecessary __packed attribute
> > - Add all EV_EFI_* event definition
> > - Create common function to prepare 8-byte aligned image
> > - Add measurement for EV_EFI_BOOT_SERVICES_DRIVER and
> >   EV_EFI_RUNTIME_SERVICES_DRIVER
> > - Use efi_search_protocol() to get device_path
> > - Add function comment
> >
> >  include/efi_loader.h  |   6 +
> >  include/efi_tcg2.h|   9 ++
> >  include/tpm-v2.h  |  18 +++
> >  lib/efi_loader/Kconfig|   1 +
> >  lib/efi_loader/efi_image_loader.c |  59 +++--
> >  lib/efi_loader/efi_tcg2.c | 207 --
> >  6 files changed, 276 insertions(+), 24 deletions(-)
> >
> > diff --git a/include/efi_loader.h b/include/efi_loader.h
> > index de1a496a97..9f2854a255 100644
> > --- a/include/efi_loader.h
> > +++ b/include/efi_loader.h
> > @@ -426,6 +426,10 @@ efi_status_t efi_disk_register(void);
> >  efi_status_t efi_rng_register(void);
> >  /* Called by efi_init_obj_list() to install EFI_TCG2_PROTOCOL */
> >  efi_status_t efi_tcg2_register(void);
> > +/* measure the pe-coff image, extend PCR and add Event Log */
> > +efi_status_t tcg2_measure_pe_image(void *efi, u64 efi_size,
> > +struct efi_loaded_image_obj *handle,
> > +struct efi_loaded_image 
> > *loaded_image_info);
> >  /* Create handles and protocols for the partitions of a block device */
> >  int efi_disk_create_partitions(efi_handle_t parent, struct blk_desc *desc,
> >  const char *if_typename, int diskid,
> > @@ -847,6 +851,8 @@ bool efi_secure_boot_enabled(void);
> >
> >  bool efi_capsule_auth_enabled(void);
> >
> > +void *efi_prepare_aligned_image(void *efi, u64 *efi_size, void **new_efi);
> > +
> >  bool efi_image_parse(void *efi, size_t len, struct efi_image_regions 
> > **regp,
> >WIN_CERTIFICATE **auth, size_t *auth_len);
> >
> > diff --git a/include/efi_tcg2.h b/include/efi_tcg2.h
> > index 40e241ce31..bcfb98168a 100644
> > --- a/include/efi_tcg2.h
> > +++ b/include/efi_tcg2.h
> > @@ -9,6 +9,7 @@
> >  #if !defined _EFI_TCG2_PROTOCOL_H_
> >  #define _EFI_TCG2_PROTOCOL_H_
> >
> > +#include 
> >  #include 
> >
> >  #define EFI_TCG2_PROTOCOL_GUID \
> > @@ -53,6 +54,14 @@ struct efi_tcg2_event {
> >   u8 event[];
> >  } __packed;
> >
> > +struct uefi_image_load_event {
> > + efi_physical_addr_t image_location_in_memory;
> > + u64 image_length_in_memory;
> > + u64 image_link_time_address;
> > + u64 length_of_device_path;
> > + struct efi_device_path device_path[];
> > +};
> > +
> >  struct efi_tcg2_boot_service_capability {
> >   u8 size;
> >   struct efi_tcg2_version structure_version;
> > diff --git a/include/tpm-v2.h b/include/tpm-v2.h
> > index 7de7d6a57d..247b386967 100644
> > --- a/include/tpm-v2.h
> > +++ b/include/tpm-v2.h
> > @@ -70,6 +70,24 @@ struct udevice;
> >  #define EV_TABLE_OF_DEVICES  ((u32)0x000B)
> >  #define EV_COMPACT_HASH  ((u32)0x000C)
> >
> > +/*
> > + * event types, cf.
> > + * "TCG PC Client Platform Firmware Profile Specification", Family "2.0"
> > + * rev 1.04, June 3, 2019
> > + */
> > +#define EV_EFI_EVENT_BASE((u32)0x8000)
> > +#define EV_EFI_VARIABLE_DRIVER_CONFIG((u32)0x8001)
> > +#define EV_EFI_VARIABLE_BOOT ((u32)0x8002)
> > +#define EV_EFI_BOOT_SERVICES_APPLICATION ((u32)0x8003)
> > +#define EV_EFI_BOOT_SERVICES_DRIVER  ((u32)0x8004)
> > +#define EV_EFI_RUNTIME_SERVICES_DRIVER   ((u32)0x8005)
> > +#define EV_EFI_GPT_EVENT ((u32)0x8006)
> > +#define EV_EFI_ACTION((u32)0x8007)
> > +#define EV_EFI_PLATFORM_FIRMWARE_BLOB((u32)0x8008)
> > +#define EV_EFI_HANDOFF_TABLES((u32)0x8009)
> > +#define EV_EFI_HCRTM_EVENT   ((u32)0x8010)
> > +#define EV_EFI_VARIABLE_AUTHORITY((u32)0x80E0)
> > +
> >  /* TPMS_TAGGED_PROPERTY Structur

Re: [PATCH v8 3/3] efi_loader: add PE/COFF image measurement

2021-05-25 Thread Heinrich Schuchardt
On 14.05.21 02:53, Masahisa Kojima wrote:
> "TCG PC Client Platform Firmware Profile Specification"
> requires to measure every attempt to load and execute
> a OS Loader(a UEFI application) into PCR[4].
> This commit adds the PE/COFF image measurement, extends PCR,
> and appends measurement into Event Log.
>
> Acked-by: Ilias Apalodimas 
> Tested-by: Ilias Apalodimas 
> Signed-off-by: Masahisa Kojima 
> ---
>
> (no changes since v7)
>
> Changes in v7:
> - include hash-checksum.h instead of rsa.h
> - select HASH_CALCULATE in Kconfig, not to update lib/Makefile
> - rebased the base code
>
> Changes in v6:
> - update lib/Makefile to add hash-checksum.c as a compilation target
>
> (no changes since v2)
>
> Changes in v2:
> - Remove duplicate  include
> - Remove unnecessary __packed attribute
> - Add all EV_EFI_* event definition
> - Create common function to prepare 8-byte aligned image
> - Add measurement for EV_EFI_BOOT_SERVICES_DRIVER and
>   EV_EFI_RUNTIME_SERVICES_DRIVER
> - Use efi_search_protocol() to get device_path
> - Add function comment
>
>  include/efi_loader.h  |   6 +
>  include/efi_tcg2.h|   9 ++
>  include/tpm-v2.h  |  18 +++
>  lib/efi_loader/Kconfig|   1 +
>  lib/efi_loader/efi_image_loader.c |  59 +++--
>  lib/efi_loader/efi_tcg2.c | 207 --
>  6 files changed, 276 insertions(+), 24 deletions(-)
>
> diff --git a/include/efi_loader.h b/include/efi_loader.h
> index de1a496a97..9f2854a255 100644
> --- a/include/efi_loader.h
> +++ b/include/efi_loader.h
> @@ -426,6 +426,10 @@ efi_status_t efi_disk_register(void);
>  efi_status_t efi_rng_register(void);
>  /* Called by efi_init_obj_list() to install EFI_TCG2_PROTOCOL */
>  efi_status_t efi_tcg2_register(void);
> +/* measure the pe-coff image, extend PCR and add Event Log */
> +efi_status_t tcg2_measure_pe_image(void *efi, u64 efi_size,
> +struct efi_loaded_image_obj *handle,
> +struct efi_loaded_image *loaded_image_info);
>  /* Create handles and protocols for the partitions of a block device */
>  int efi_disk_create_partitions(efi_handle_t parent, struct blk_desc *desc,
>  const char *if_typename, int diskid,
> @@ -847,6 +851,8 @@ bool efi_secure_boot_enabled(void);
>
>  bool efi_capsule_auth_enabled(void);
>
> +void *efi_prepare_aligned_image(void *efi, u64 *efi_size, void **new_efi);
> +
>  bool efi_image_parse(void *efi, size_t len, struct efi_image_regions **regp,
>WIN_CERTIFICATE **auth, size_t *auth_len);
>
> diff --git a/include/efi_tcg2.h b/include/efi_tcg2.h
> index 40e241ce31..bcfb98168a 100644
> --- a/include/efi_tcg2.h
> +++ b/include/efi_tcg2.h
> @@ -9,6 +9,7 @@
>  #if !defined _EFI_TCG2_PROTOCOL_H_
>  #define _EFI_TCG2_PROTOCOL_H_
>
> +#include 
>  #include 
>
>  #define EFI_TCG2_PROTOCOL_GUID \
> @@ -53,6 +54,14 @@ struct efi_tcg2_event {
>   u8 event[];
>  } __packed;
>
> +struct uefi_image_load_event {
> + efi_physical_addr_t image_location_in_memory;
> + u64 image_length_in_memory;
> + u64 image_link_time_address;
> + u64 length_of_device_path;
> + struct efi_device_path device_path[];
> +};
> +
>  struct efi_tcg2_boot_service_capability {
>   u8 size;
>   struct efi_tcg2_version structure_version;
> diff --git a/include/tpm-v2.h b/include/tpm-v2.h
> index 7de7d6a57d..247b386967 100644
> --- a/include/tpm-v2.h
> +++ b/include/tpm-v2.h
> @@ -70,6 +70,24 @@ struct udevice;
>  #define EV_TABLE_OF_DEVICES  ((u32)0x000B)
>  #define EV_COMPACT_HASH  ((u32)0x000C)
>
> +/*
> + * event types, cf.
> + * "TCG PC Client Platform Firmware Profile Specification", Family "2.0"
> + * rev 1.04, June 3, 2019
> + */
> +#define EV_EFI_EVENT_BASE((u32)0x8000)
> +#define EV_EFI_VARIABLE_DRIVER_CONFIG((u32)0x8001)
> +#define EV_EFI_VARIABLE_BOOT ((u32)0x8002)
> +#define EV_EFI_BOOT_SERVICES_APPLICATION ((u32)0x8003)
> +#define EV_EFI_BOOT_SERVICES_DRIVER  ((u32)0x8004)
> +#define EV_EFI_RUNTIME_SERVICES_DRIVER   ((u32)0x8005)
> +#define EV_EFI_GPT_EVENT ((u32)0x8006)
> +#define EV_EFI_ACTION((u32)0x8007)
> +#define EV_EFI_PLATFORM_FIRMWARE_BLOB((u32)0x8008)
> +#define EV_EFI_HANDOFF_TABLES((u32)0x8009)
> +#define EV_EFI_HCRTM_EVENT   ((u32)0x8010)
> +#define EV_EFI_VARIABLE_AUTHORITY((u32)0x80E0)
> +
>  /* TPMS_TAGGED_PROPERTY Structure */
>  struct tpms_tagged_property {
>   u32 property;
> diff --git a/lib/efi_loader/Kconfig b/lib/efi_loader/Kconfig
> index 98845b8ba3..0e6200fa25 100644
> --- a/lib/efi_loader/Kconfig
> +++ b/lib/efi_loader/Kconfig
> @@ -309,6 +309,7 @@ config EFI_TCG2_PROTOCOL
>   select SHA512_ALGO
>   selec

Re: [PATCH v8 3/3] efi_loader: add PE/COFF image measurement

2021-05-24 Thread Masahisa Kojima
On Mon, 24 May 2021 at 21:53, Ilias Apalodimas
 wrote:
>
> new_efi);
> > +
> >  bool efi_image_parse(void *efi, size_t len, struct efi_image_regions 
> > **regp,
> >WIN_CERTIFICATE **auth, size_t *auth_len);
> >
> > diff --git a/include/efi_tcg2.h b/include/efi_tcg2.h
> > index 40e241ce31..bcfb98168a 100644
> > --- a/include/efi_tcg2.h
> > +++ b/include/efi_tcg2.h
> > @@ -9,6 +9,7 @@
> >  #if !defined _EFI_TCG2_PROTOCOL_H_
> >  #define _EFI_TCG2_PROTOCOL_H_
> >
> > +#include 
> >  #include 
> >
> >  #define EFI_TCG2_PROTOCOL_GUID \
> > @@ -53,6 +54,14 @@ struct efi_tcg2_event {
> >   u8 event[];
> >  } __packed;
> >
> > +struct uefi_image_load_event {
> > + efi_physical_addr_t image_location_in_memory;
> > + u64 image_length_in_memory;
> > + u64 image_link_time_address;
> > + u64 length_of_device_path;
> > + struct efi_device_path device_path[];
> > +};
> > +
> >  struct efi_tcg2_boot_service_capability {
> >   u8 size;
> >   struct efi_tcg2_version structure_version;
> > diff --git a/include/tpm-v2.h b/include/tpm-v2.h
> > index 7de7d6a57d..247b386967 100644
> > --- a/include/tpm-v2.h
> > +++ b/include/tpm-v2.h
> > @@ -70,6 +70,24 @@ struct udevice;
> >  #define EV_TABLE_OF_DEVICES  ((u32)0x000B)
> >  #define EV_COMPACT_HASH  ((u32)0x000C)
> >
> > +/*
> > + * event types, cf.
> > + * "TCG PC Client Platform Firmware Profile Specification", Family "2.0"
> > + * rev 1.04, June 3, 2019
> > + */
> > +#define EV_EFI_EVENT_BASE((u32)0x8000)
> > +#define EV_EFI_VARIABLE_DRIVER_CONFIG((u32)0x8001)
> > +#define EV_EFI_VARIABLE_BOOT ((u32)0x8002)
> > +#define EV_EFI_BOOT_SERVICES_APPLICATION ((u32)0x8003)
> > +#define EV_EFI_BOOT_SERVICES_DRIVER  ((u32)0x8004)
> > +#define EV_EFI_RUNTIME_SERVICES_DRIVER   ((u32)0x8005)
> > +#define EV_EFI_GPT_EVENT ((u32)0x8006)
> > +#define EV_EFI_ACTION((u32)0x8007)
> > +#define EV_EFI_PLATFORM_FIRMWARE_BLOB((u32)0x8008)
> > +#define EV_EFI_HANDOFF_TABLES((u32)0x8009)
> > +#define EV_EFI_HCRTM_EVENT   ((u32)0x8010)
> > +#define EV_EFI_VARIABLE_AUTHORITY((u32)0x80E0)
> > +
> >  /* TPMS_TAGGED_PROPERTY Structure */
> >  struct tpms_tagged_property {
> >   u32 property;
> > diff --git a/lib/efi_loader/Kconfig b/lib/efi_loader/Kconfig
> > index 98845b8ba3..0e6200fa25 100644
> > --- a/lib/efi_loader/Kconfig
> > +++ b/lib/efi_loader/Kconfig
> > @@ -309,6 +309,7 @@ config EFI_TCG2_PROTOCOL
> >   select SHA512_ALGO
> >   select SHA384
> >   select SHA512
> > + select HASH_CALCULATE
> >   help
> > Provide a EFI_TCG2_PROTOCOL implementation using the TPM hardware
> > of the platform.
> > diff --git a/lib/efi_loader/efi_image_loader.c 
> > b/lib/efi_loader/efi_image_loader.c
> > index fe1ee198e2..f37a85e56e 100644
> > --- a/lib/efi_loader/efi_image_loader.c
> > +++ b/lib/efi_loader/efi_image_loader.c
> > @@ -302,6 +302,40 @@ static int cmp_pe_section(const void *arg1, const void 
> > *arg2)
> >   return 1;
> >  }
> >
> > +/**
> > + * efi_prepare_aligned_image() - prepare 8-byte aligned image
> > + * @efi: pointer to the EFI binary
> > + * @efi_size:size of @efi binary
> > + * @new_efi: pointer to the newly allocated image
> > + *
> > + * If @efi is not 8-byte aligned, this function newly allocates
> > + * the image buffer and updates @efi_size.
> > + *
> > + * Return:   valid pointer to a image, return NULL if allocation fails.
> > + */
> > +void *efi_prepare_aligned_image(void *efi, u64 *efi_size, void **new_efi)
> > +{
> > + size_t new_efi_size;
> > + void *p;
> > +
> > + /*
> > +  * Size must be 8-byte aligned and the trailing bytes must be
> > +  * zero'ed. Otherwise hash value may be incorrect.
> > +  */
> > + if (!IS_ALIGNED(*efi_size, 8)) {
> > + new_efi_size = ALIGN(*efi_size, 8);
> > + p = calloc(new_efi_size, 1);
> > + if (!p)
> > + return NULL;
> > + memcpy(p, efi, *efi_size);
> > + *efi_size = new_efi_size;
>
> Do we really need new_efi here?  I might be missing some context for the
> original code, but since we return the new pointer, can't we just
> use that in the caller? If so the whole void **new_efi is not needed?

new_efi is required.
The caller uses returned pointer, it will be the pointer to the
original efi image or newly allocated buffer. Caller will need new_efi
to free the newly allocated buffer.

>
> > +
>
> [...]
>
> > + ret = __get_active_pcr_banks(&active);
> > + if (ret != EFI_SUCCESS) {
> > + ret = EFI_DEVICE_ERROR;
>
> __get_active_pcr_banks is supposed to return the correct efi_status_t code.
> I don't think we need EFI_

Re: [PATCH v8 3/3] efi_loader: add PE/COFF image measurement

2021-05-24 Thread Ilias Apalodimas
new_efi);
> +
>  bool efi_image_parse(void *efi, size_t len, struct efi_image_regions **regp,
>WIN_CERTIFICATE **auth, size_t *auth_len);
>  
> diff --git a/include/efi_tcg2.h b/include/efi_tcg2.h
> index 40e241ce31..bcfb98168a 100644
> --- a/include/efi_tcg2.h
> +++ b/include/efi_tcg2.h
> @@ -9,6 +9,7 @@
>  #if !defined _EFI_TCG2_PROTOCOL_H_
>  #define _EFI_TCG2_PROTOCOL_H_
>  
> +#include 
>  #include 
>  
>  #define EFI_TCG2_PROTOCOL_GUID \
> @@ -53,6 +54,14 @@ struct efi_tcg2_event {
>   u8 event[];
>  } __packed;
>  
> +struct uefi_image_load_event {
> + efi_physical_addr_t image_location_in_memory;
> + u64 image_length_in_memory;
> + u64 image_link_time_address;
> + u64 length_of_device_path;
> + struct efi_device_path device_path[];
> +};
> +
>  struct efi_tcg2_boot_service_capability {
>   u8 size;
>   struct efi_tcg2_version structure_version;
> diff --git a/include/tpm-v2.h b/include/tpm-v2.h
> index 7de7d6a57d..247b386967 100644
> --- a/include/tpm-v2.h
> +++ b/include/tpm-v2.h
> @@ -70,6 +70,24 @@ struct udevice;
>  #define EV_TABLE_OF_DEVICES  ((u32)0x000B)
>  #define EV_COMPACT_HASH  ((u32)0x000C)
>  
> +/*
> + * event types, cf.
> + * "TCG PC Client Platform Firmware Profile Specification", Family "2.0"
> + * rev 1.04, June 3, 2019
> + */
> +#define EV_EFI_EVENT_BASE((u32)0x8000)
> +#define EV_EFI_VARIABLE_DRIVER_CONFIG((u32)0x8001)
> +#define EV_EFI_VARIABLE_BOOT ((u32)0x8002)
> +#define EV_EFI_BOOT_SERVICES_APPLICATION ((u32)0x8003)
> +#define EV_EFI_BOOT_SERVICES_DRIVER  ((u32)0x8004)
> +#define EV_EFI_RUNTIME_SERVICES_DRIVER   ((u32)0x8005)
> +#define EV_EFI_GPT_EVENT ((u32)0x8006)
> +#define EV_EFI_ACTION((u32)0x8007)
> +#define EV_EFI_PLATFORM_FIRMWARE_BLOB((u32)0x8008)
> +#define EV_EFI_HANDOFF_TABLES((u32)0x8009)
> +#define EV_EFI_HCRTM_EVENT   ((u32)0x8010)
> +#define EV_EFI_VARIABLE_AUTHORITY((u32)0x80E0)
> +
>  /* TPMS_TAGGED_PROPERTY Structure */
>  struct tpms_tagged_property {
>   u32 property;
> diff --git a/lib/efi_loader/Kconfig b/lib/efi_loader/Kconfig
> index 98845b8ba3..0e6200fa25 100644
> --- a/lib/efi_loader/Kconfig
> +++ b/lib/efi_loader/Kconfig
> @@ -309,6 +309,7 @@ config EFI_TCG2_PROTOCOL
>   select SHA512_ALGO
>   select SHA384
>   select SHA512
> + select HASH_CALCULATE
>   help
> Provide a EFI_TCG2_PROTOCOL implementation using the TPM hardware
> of the platform.
> diff --git a/lib/efi_loader/efi_image_loader.c 
> b/lib/efi_loader/efi_image_loader.c
> index fe1ee198e2..f37a85e56e 100644
> --- a/lib/efi_loader/efi_image_loader.c
> +++ b/lib/efi_loader/efi_image_loader.c
> @@ -302,6 +302,40 @@ static int cmp_pe_section(const void *arg1, const void 
> *arg2)
>   return 1;
>  }
>  
> +/**
> + * efi_prepare_aligned_image() - prepare 8-byte aligned image
> + * @efi: pointer to the EFI binary
> + * @efi_size:size of @efi binary
> + * @new_efi: pointer to the newly allocated image
> + *
> + * If @efi is not 8-byte aligned, this function newly allocates
> + * the image buffer and updates @efi_size.
> + *
> + * Return:   valid pointer to a image, return NULL if allocation fails.
> + */
> +void *efi_prepare_aligned_image(void *efi, u64 *efi_size, void **new_efi)
> +{
> + size_t new_efi_size;
> + void *p;
> +
> + /*
> +  * Size must be 8-byte aligned and the trailing bytes must be
> +  * zero'ed. Otherwise hash value may be incorrect.
> +  */
> + if (!IS_ALIGNED(*efi_size, 8)) {
> + new_efi_size = ALIGN(*efi_size, 8);
> + p = calloc(new_efi_size, 1);
> + if (!p)
> + return NULL;
> + memcpy(p, efi, *efi_size);
> + *efi_size = new_efi_size;

Do we really need new_efi here?  I might be missing some context for the 
original code, but since we return the new pointer, can't we just
use that in the caller? If so the whole void **new_efi is not needed?

> +

[...]

> + ret = __get_active_pcr_banks(&active);
> + if (ret != EFI_SUCCESS) {
> + ret = EFI_DEVICE_ERROR;

__get_active_pcr_banks is supposed to return the correct efi_status_t code.
I don't think we need EFI_DEVICE_ERROR here.

 
Thanks!
/Ilias


[PATCH v8 3/3] efi_loader: add PE/COFF image measurement

2021-05-13 Thread Masahisa Kojima
"TCG PC Client Platform Firmware Profile Specification"
requires to measure every attempt to load and execute
a OS Loader(a UEFI application) into PCR[4].
This commit adds the PE/COFF image measurement, extends PCR,
and appends measurement into Event Log.

Acked-by: Ilias Apalodimas 
Tested-by: Ilias Apalodimas 
Signed-off-by: Masahisa Kojima 
---

(no changes since v7)

Changes in v7:
- include hash-checksum.h instead of rsa.h
- select HASH_CALCULATE in Kconfig, not to update lib/Makefile
- rebased the base code

Changes in v6:
- update lib/Makefile to add hash-checksum.c as a compilation target

(no changes since v2)

Changes in v2:
- Remove duplicate  include
- Remove unnecessary __packed attribute
- Add all EV_EFI_* event definition
- Create common function to prepare 8-byte aligned image
- Add measurement for EV_EFI_BOOT_SERVICES_DRIVER and
  EV_EFI_RUNTIME_SERVICES_DRIVER
- Use efi_search_protocol() to get device_path
- Add function comment

 include/efi_loader.h  |   6 +
 include/efi_tcg2.h|   9 ++
 include/tpm-v2.h  |  18 +++
 lib/efi_loader/Kconfig|   1 +
 lib/efi_loader/efi_image_loader.c |  59 +++--
 lib/efi_loader/efi_tcg2.c | 207 --
 6 files changed, 276 insertions(+), 24 deletions(-)

diff --git a/include/efi_loader.h b/include/efi_loader.h
index de1a496a97..9f2854a255 100644
--- a/include/efi_loader.h
+++ b/include/efi_loader.h
@@ -426,6 +426,10 @@ efi_status_t efi_disk_register(void);
 efi_status_t efi_rng_register(void);
 /* Called by efi_init_obj_list() to install EFI_TCG2_PROTOCOL */
 efi_status_t efi_tcg2_register(void);
+/* measure the pe-coff image, extend PCR and add Event Log */
+efi_status_t tcg2_measure_pe_image(void *efi, u64 efi_size,
+  struct efi_loaded_image_obj *handle,
+  struct efi_loaded_image *loaded_image_info);
 /* Create handles and protocols for the partitions of a block device */
 int efi_disk_create_partitions(efi_handle_t parent, struct blk_desc *desc,
   const char *if_typename, int diskid,
@@ -847,6 +851,8 @@ bool efi_secure_boot_enabled(void);
 
 bool efi_capsule_auth_enabled(void);
 
+void *efi_prepare_aligned_image(void *efi, u64 *efi_size, void **new_efi);
+
 bool efi_image_parse(void *efi, size_t len, struct efi_image_regions **regp,
 WIN_CERTIFICATE **auth, size_t *auth_len);
 
diff --git a/include/efi_tcg2.h b/include/efi_tcg2.h
index 40e241ce31..bcfb98168a 100644
--- a/include/efi_tcg2.h
+++ b/include/efi_tcg2.h
@@ -9,6 +9,7 @@
 #if !defined _EFI_TCG2_PROTOCOL_H_
 #define _EFI_TCG2_PROTOCOL_H_
 
+#include 
 #include 
 
 #define EFI_TCG2_PROTOCOL_GUID \
@@ -53,6 +54,14 @@ struct efi_tcg2_event {
u8 event[];
 } __packed;
 
+struct uefi_image_load_event {
+   efi_physical_addr_t image_location_in_memory;
+   u64 image_length_in_memory;
+   u64 image_link_time_address;
+   u64 length_of_device_path;
+   struct efi_device_path device_path[];
+};
+
 struct efi_tcg2_boot_service_capability {
u8 size;
struct efi_tcg2_version structure_version;
diff --git a/include/tpm-v2.h b/include/tpm-v2.h
index 7de7d6a57d..247b386967 100644
--- a/include/tpm-v2.h
+++ b/include/tpm-v2.h
@@ -70,6 +70,24 @@ struct udevice;
 #define EV_TABLE_OF_DEVICES((u32)0x000B)
 #define EV_COMPACT_HASH((u32)0x000C)
 
+/*
+ * event types, cf.
+ * "TCG PC Client Platform Firmware Profile Specification", Family "2.0"
+ * rev 1.04, June 3, 2019
+ */
+#define EV_EFI_EVENT_BASE  ((u32)0x8000)
+#define EV_EFI_VARIABLE_DRIVER_CONFIG  ((u32)0x8001)
+#define EV_EFI_VARIABLE_BOOT   ((u32)0x8002)
+#define EV_EFI_BOOT_SERVICES_APPLICATION   ((u32)0x8003)
+#define EV_EFI_BOOT_SERVICES_DRIVER((u32)0x8004)
+#define EV_EFI_RUNTIME_SERVICES_DRIVER ((u32)0x8005)
+#define EV_EFI_GPT_EVENT   ((u32)0x8006)
+#define EV_EFI_ACTION  ((u32)0x8007)
+#define EV_EFI_PLATFORM_FIRMWARE_BLOB  ((u32)0x8008)
+#define EV_EFI_HANDOFF_TABLES  ((u32)0x8009)
+#define EV_EFI_HCRTM_EVENT ((u32)0x8010)
+#define EV_EFI_VARIABLE_AUTHORITY  ((u32)0x80E0)
+
 /* TPMS_TAGGED_PROPERTY Structure */
 struct tpms_tagged_property {
u32 property;
diff --git a/lib/efi_loader/Kconfig b/lib/efi_loader/Kconfig
index 98845b8ba3..0e6200fa25 100644
--- a/lib/efi_loader/Kconfig
+++ b/lib/efi_loader/Kconfig
@@ -309,6 +309,7 @@ config EFI_TCG2_PROTOCOL
select SHA512_ALGO
select SHA384
select SHA512
+   select HASH_CALCULATE
help
  Provide a EFI_TCG2_PROTOCOL implementation using the TPM hardware
  of the platform.
diff --git a/lib/efi_loader/efi_image_loader.c 
b/lib/efi_loader/efi_image_loader