[PATCH 10/16] efi_loader: UEFI variable persistence

Ilias Apalodimas
2020-04-06T16:06:35Z

On Fri, Mar 27, 2020 at 11:30:47AM +0100, Heinrich Schuchardt wrote:
> On 3/27/20 9:07 AM, Punit Agrawal wrote:
> > Heinrich Schuchardt <xypron.glpk@gmx.de> writes:
> >
> > > Persist non-volatile UEFI variables in a file on the EFI system partition.
> > >
> > > The file is written:
> > >
> > > * whenever a non-volatile UEFI variable is changed after initialization
> > > of the UEFI sub-system.
> > > * upon ExitBootServices()
> >
> > I might be missing something but how does this cope with the ESP being
> > on a storage medium access to which is owned by the OS at runtime? e.g.,
> > partition on eMMC or SATA drive.
>
> This development does not guard against manipulation by the OS.
>
> Ilias is cureently working on a solution for ATF based devices that will
> provide secure storage for variables.
>

Ok sorry for jumping in late, I was actually coding what Heinrich mentioned and
I do have a rough prototype.

I think it's time we (Linaro) expose the idea we had a while back a bit more.
The problem we identified is that the current EDK2 implementation on Arm uses
SPM (Secure Partition Manager). Although this works quite well, SPM and
SPD(Secure Payload Dispatcher) are mutually exclusive. So running SPM and
variable storage, means no OP-TEE.

What we ended up doing, is run the EDK2 StandAloneMM application,
responsible for *all* the handling of UEFI variables in an isolated OP-TEE
partition.
By doing so we can add variable storage on U-boot as an 'external' library which
also hapopens to be 'firmware agnostic'.
The only thing U-Boot has to do is route the Get/Set variable to the Secure World
and if there's an OP-TEE instance running the variables will be handled by that.
This includes authentication and writing them to a medium. The medium can either
be a dedicated flash on Secure world, an RPMB partiiton of the eMMC or a
file in some filesystem.

Storing them on a dedicated Secure world flash, means that the vendor has to
provide that driver in EDK2.
Storing them on an eMMC has a single requirement. An eMMC driver in U-boot, since
OP-TEE uses an existing U-Boot supplicant to access the RPMB.
Storing them on a filesystem through OP-TEE is not implemented by us yet but it
might worth a try since at least the variable verification and authentication
will be executed in Secure World.
In any case this renders U-Boot agnostic to the actual variables, again, as long
it routes the requests to the secure world.

That being said I do believe Heinrich's patch is very useful, since if U-Boot
doesn't run on an Arm core, you still have a way of providing some kind of
secure storage (and a fallback for Arm devices without options (1), (2)).

So, imho, the things need we need to discuss further is:
- EDK2 uses a firmware block protocol, with it's own defined hears and a
Fault Tolerant Write backup partitions. By using the solution I mentioned, you
inherit that as well. Should the 'raw' U-boot code follow that example and use
the same format for the file? Or is Heinrich's format adequate?
The obvious advantage is that systsems can switch between EDK2/U-Boot and
still be able to use the same variable format.
The disadvantage is that it's kind of complicated for my taste :)

- Should U-boot try to offer similar code for variable authentation and
verification? The reason we decided to run StandAloneMM and get those from
EDK2, is that the whole variable format, attributes and auth of UEFI variables
is complex and big. Does it make sense to add that on U-Boot keeping in mind
it's something running on Non-secure world?

Regards
/Ilias

> >
> > >
[...]
> > > + if (r || len != actlen)
> > > + ret = EFI_DEVICE_ERROR;
> > > +
> > > +error:
> > > + if (ret != EFI_SUCCESS)
> > > + printf("Failed to persist EFI variables\n");
> > > + free(buf);
> > > + return ret;
> > > +#else
> > > + return EFI_SUCCESS;
> > > +#endif
> > > +}
> > > +
> >
> > [...]
> >
>