[PATCH] efi_loader: explicitly return EFI_UNSUPPORTED for TCG 1.0 compatibility
Ilias Apalodimas
ilias.apalodimas at linaro.org
Wed May 31 19:40:50 CEST 2023
Hi Stuart,
[...]
> >> EFI_TCG2_EVENT_ALGORITHM_BITMAP ActivePcrBanks
> >> };
> >>
> >> The intent in the TCG spec is for the caller to be able to
> >> determine the size of the struct by passing in a small
> >> buffer (e.g. 1 byte buffer), and then the firmware
> >> should return sizeof(EFI_TCG2_BOOT_SERVICE_CAPABILITY) in the
> >> 1-byte "Size" field. And the return value should be
> >> EFI_BUFFER_TOO_SMALL as per the spec.
> >>
> >> In order to detect a 1.0 client, which you don't want to support,
> >> I think you need a _new_ check that is something like this:
> >>
> >> // detect 1.0 client
> >> if (capability->size < sizeof(*capability) &&
> >> capability->size >= offsetof(EFI_TCG2_BOOT_SERVICE_CAPABILITY,
> >> NumberOfPcrBanks)) {
> >> efi_ret = EFI_UNSUPPORTED;
> >> goto out;
> >> }
> >>
> >> The last field in the 1.0 struct was ManufacturerID, so you should
> >> be able to detect 1.0 clients that expect that based on the size they
> >> pass in.
> >
> > The patch doesn't show the entire u-boot code there and is a bit misleading.
> > There's another check that precedes the one I am patching, which if I
> > am reading it correctly does exactly what you describe
> >
> > #define BOOT_SERVICE_CAPABILITY_MIN \
> > offsetof(struct efi_tcg2_boot_service_capability, number_of_pcr_banks)
> > if (capability->size < BOOT_SERVICE_CAPABILITY_MIN) {
> > capability->size = BOOT_SERVICE_CAPABILITY_MIN;
> > efi_ret = EFI_BUFFER_TOO_SMALL;
> > goto out;
> > }
>
> I took a look at the u-boot code. What I think we want is this:
>
> diff --git a/include/efi_tcg2.h b/include/efi_tcg2.h
> index b1c3abd097..6a46d9e51c 100644
> --- a/include/efi_tcg2.h
> +++ b/include/efi_tcg2.h
> @@ -126,7 +126,7 @@ struct efi_tcg2_boot_service_capability {
> };
>
> /* up to and including the vendor ID (manufacturer_id) field */
> -#define BOOT_SERVICE_CAPABILITY_MIN \
> +#define BOOT_SERVICE_CAPABILITY_1_0 \
> offsetof(struct efi_tcg2_boot_service_capability,
> number_of_pcr_banks)
>
> #define TCG_EFI_SPEC_ID_EVENT_SIGNATURE_03 "Spec ID Event03"
> diff --git a/lib/efi_loader/efi_tcg2.c b/lib/efi_loader/efi_tcg2.c
> index a83ae7a46c..d37b896b7e 100644
> --- a/lib/efi_loader/efi_tcg2.c
> +++ b/lib/efi_loader/efi_tcg2.c
> @@ -742,15 +742,15 @@ efi_tcg2_get_capability(struct efi_tcg2_protocol
> *this,
> goto out;
> }
>
> - if (capability->size < BOOT_SERVICE_CAPABILITY_MIN) {
> - capability->size = BOOT_SERVICE_CAPABILITY_MIN;
> + if (capability->size < BOOT_SERVICE_CAPABILITY_1_0) {
> + capability->size = sizeof(*capability);
> efi_ret = EFI_BUFFER_TOO_SMALL;
> goto out;
> }
>
> if (capability->size < sizeof(*capability)) {
> capability->size = sizeof(*capability);
> - efi_ret = EFI_BUFFER_TOO_SMALL;
> + efi_ret = EFI_UNSUPPORTED;
> goto out;
> }
>
> That is:
>
> -if the passed in size is less than the 1.0 struct size
> then return sizeof() the full struct. This allows
> client to query and determine the supported struct
> size
>
> -to detect and reject 1.0 clients, if the passed in
> size is >= 1.0 struct size AND less than sizeof(*capability)
> then return EFI_UNSUPPORTED
>
> Does that make sense?
It does but that violates the spec once again.
The spec says that the firmware should return
BOOT_SERVICE_CAPABILITY_MIN if the size is less than the size of the
EFI_TCG2_BOOT_SERVICE_CAPABILITY.
The current logic is similar, the only thing that differs on your
patch is the size of the struct we return.
Thanks
/Ilias
>
> Thanks,
> Stuart
More information about the U-Boot
mailing list