Hello everyone. My name is Annie, and I'm a software engineer at Red Hat. Today, I'll
be talking about Fookie, which is UKI with guest farmer image model. Hopefully, everyone
is White White early morning. Hopefully, if not, then I can get you guys all white
away and alert with this. So, we're involved. Me, Vitali, who is the resident here, the
next speaker, Alex, who is right there. He's an original idea, and then a bunch of us
follow and good from Red Hat and hurled from Adelabs. I miss the tank Leonard for actually
getting up to speed with this project and helping us through all the system D and ETI bits
on the upstream side. So, thanks Leonard very much, and also for referencing this talk yesterday
at his presentation. So, how this talk is going to go? Initially, I'm going to give a
brief background of the basic confidential stuff and our motivation, what problem we're trying
to solve and how we're trying to solve it. And then I'll go into the new stuff, which
is the UKI, the Fookie bits. And then I'm going to describe some of the current status
and how things are looking on the upstream with the different bits of work streams.
So, what is the combination of them? So, on the left is the traditional virtual machine,
the hypervisor, which is running on the host, is actually able to look into guest memory pages,
able to read and also manipulate those pages if it wants to, and the guest is no control over
that. Welcome to confidential VMs. Here, a part of the virtual machine memory is encrypted,
so that the host and the hypervisor no longer is able to manipulate guest memory, at least
the parts that are encrypted. So, the guest can keep its circuit stuff, its things that
it wants the host to not know or tamper with. So, that's the fundamentals of confidential
VM. There are a lot of hardware technologies, both on the internal and MD side that guarantees
some of this confidentiality. For example, on the MD, we have serve service and service
and P. And the details of this is beyond the scope of this talk. On the intel, we have intel
specific technology that guarantees encryption of guest memory. There is one thing, though,
that the host and the hypervisor can still disrupt the execution of the guest. So, they can
deprive the guest of CPU cycles, that is still possible, but that's beyond the proof of confidential
computing. And then the description, so the secrets can still be in the guest disk images
and the guest is responsible for encrypling that as well. So, that is also outside the
pervue of this talk. So, what are we trying to do here? So, what we are trying to do is
we are trying to make sure that the confidentiality with respect to guest firmware is achieved
when the guest is deployed in an external cloud provider, for example, AWS or some other
tenant. And in theory, our idea can work on the non confidential case as well, but it makes
more sense in the confidential environment. So, why is it necessary? Because, so the guest firmware
is actually running within the context of the guest. So, it is important to make sure that
the guest is able to trust the firmware, but the problem is that in the traditional case,
the firmware comes from the cloud provider and one does necessarily know how that firmware
is built. And even though we can measure it and get hatches, the guest doesn't necessarily
know what that hatch really means. Unless there is the cloud provider changes, the
firmware, and then we get a different hash. But so, the guest can detect that the new
firmware is present, but the guest doesn't necessarily know what that really means.
The other thing is that the guest depends on things like TPM and secure UFI, variable
store, etc. And so, all of these, for all of these things, without our idea, without
this idea, the guest has to depend on the cloud providers firmware, which is not
very convenient in the confidential setup. So, our idea is that the guest brings
in its own firmware as a part of the UKI. And then we have a mechanism so that
just the guest loads it in the memory, and then there is a normal VM reset, and then the
firmware is then activated. So, the other interesting and useful thing is that we do not
need to realize the guest, just a simple normal operating system reset is good enough to
activate the firmware. From the cloud provider's perspective, this is also useful because
the cloud provider can then say update the firmware, because they might have found
some security issues or whatever. And then when the firmware changes, it's
mentioned when changes from within the guest, but the guest doesn't care, because
they're not going to run that firmware anyway. They're going to use the firmware that
it brings with it, which it knows and it trusts. And so, it really doesn't
matter what the cloud provider is doing with its own firmware.
So, the reason why we prefer that the guest brings the firmware
for with UKI is that, say for example, if the guest has provided the firmware in a
different way, like for example, maybe the cloud provider has a UI where it can
upload the firmware. Then the problem is that it requires storage on the part of the cloud
provider, which the cloud provider may not be willing to spend money on.
And the other thing is that if the firmware is actually built in as a part of its
guest storage, then the cloud provider may not actually able to read that storage,
the guest storage, because maybe it's a past storage, which the cloud provider
doesn't have access to it. So, our idea solves all these problems when we use
FUKI. Now, let's look at the broad idea of how this works. Say the virtual
machine that the ending is running brings a firmware with it as a part of the
UKI. Now, this firmware, this UKI then loads the firmware and other boot components,
like kernel image or any carding into memory. So, you can see that on the left
and the right, both cases, it's actually confidential VMs. On the left, it is running cloud
providers provided firmware, which is not necessarily trusted. On the right, it is
the same virtual machine and same Coco context, but it is running the trusted firmware, which
the end user brought with the UKI. So, in both cases, we have encrypted part of the memory
and a non-encrypted part shared part of the memory. So, the first the UKI loads these components
firmware, kernel image and a carding into the shared part of the memory. And then what it does
is that it tells the hypervisor where it loaded these components. Now, the green dot
is actually hypervisor interface through which the UKI talks to the hypervisor.
The hypervisor could be more something else. And the interface is something that is
generic, which should design something which is works across all different kinds of
hypervisor. So, now that the hypervisor knows where these components are loaded, it
the UKI initiates, once it tells the hypervisor where it loaded these components, the
boot components in the memory, it initiates a normal guest reset. And then, when hypervisor
realizes that the guest is triggering a reset, it copies the firmware, which the UKI
loaded in the shared memory into a standard location where normally you will find the firmware
for that particular platform. So, these addresses are kind of standard addresses where
farmers are loaded. And so, once the VM resets, the instruction pointer goes directly at the
address where it will find the firmware. And it does find the firmware, but now it is the
one that the guest trusts, not the one that came with the cloud provider. So, now, once
the firmware is loaded, and the guest is reset, it starts its normal execution. The firmware
validates the kernel image and any tardy, because the firmware knows which of these images
can be trusted, and it knows the hatches of the kernel image and any tardy that are
trustable. And so, the firmware is now responsible for loading the rest of the boot components,
which is kernel image in tardy, etc. So, this kind of looks like the guest memory after the
reset. Now, let's talk about why we are using UKI for bringing in the firmware. Now, UKI
is a very common standard mechanism used by most distros to already deploy kernel images
and any tardy and kernel command line. And they can be also customized for different target
environments. So, you could have UKI add-ons that are specific to the target platforms.
UKI can be signed. So, you can verify this signature that it comes from a trustable source,
like for example, Red Hat. They can be revoked using as back mechanism. So, all these things
comes free when we use UKI. This technology is already there. And the UKI can be deployed in
kernel packs management tools, like RPM or DNF or whatever. So, all of this is comes free free
when we bundle the firmware image with the UKI. So, it is very convenient container to deploy
these guest firmware images in the cloud context. So, let's see how we can actually build a
full key. So, UKI file or Python standard tool that can be used to build any UKI. So, today
you can bundle your own firmware, your kernel, any tardy, kernel image, kernel command line etc.
using UKI file. So, it is the same tool has been extended to add a new command line called
UFI firmware. And this one takes a name of directory, which contains a firmware image. And you
have multiple of these past in the command line. So, each of these directory contain different
firmware image that you want to put in this tardy to UKI. And they can be for different platforms
or they can be of different kinds of bills, get be debug build or release build or whatever.
Now, to distinguish these different firmware that are in the UKI, the name of the directory
is used as a firmware ID. So, it takes the name of the directory as an ID for the firmware
that it can match with particular tardy platform. This was Linux idea. We can see the upstream
discussion on that with Linux. So, he thought that we should just keep it simple for now. So, it takes the
directory uses that as a firmware ID. And then generates one of these sections called EFI
firmware within the UKI. Now, I will tell you how this matching happens for particular
platform. Now, some of it has already been described by Linux yesterday stock. So, I am just going
to give you a little bit more details on this. So, what happens is that the UKI calculates different
hardware IDs for the target platform called computer hardware IDs. Now, these are hashes based
on looking at different things in the hardware. And then what it does is that it goes into the
hardware ID sections in the UKI. And then tries to match one of those key values that is calculated
for the virtualized hardware with one of the entries in the hardware ID section. Now, the hardware ID
section contains a mapping between the speed value and a firmware ID string. This string can be
anything. And in our case, this string is actually the name of this directory, which is used
as the firmware ID. So, now it finds a matching entry in hardware ID that matches the speed value.
And then it goes to the UFI firmware section of the UKI and tries to find a firmware that matches
that firmware ID. So, then once it finds it, it loads the first matching entry. So, now, we have
a speed value for a particular firmware matching a specific firmware entry in this UKI. So, that is how
the firmware that is loaded in the memory matches a specific hardware. So, you can you can look
into the highly recommend looking into the recording of Leonard's truck yesterday because he briefly describes
this also. And then the thing is this, once this firmware is loaded, it will load the other boot components,
which could be the, the firmware image, sorry, the kernel inequality or the command line or the kernel
BZ or whatever. So, the task of loading the firmware entry, it is done. And then that changes loads the other stuff.
Now, this diagram you remember from few previous slides. The interesting thing is this green line here,
which is actually a well defined interface that the UKI will use to talk to this hypervisor. And this is this, this, this part is
we are already in the process of designing. And the thing is, one of the things that we have to figure out is how we can design this in a hypervisor
agnostic manner. So, that it can work across all different hypervisor. So, you have something for Kimo, a Kimo drive specific driver,
and maybe something for some other hypervisor. And then you have a hypervisor agnostic layer that then uses that interface to talk to the hypervisor
and hypervisor agnostic way. So, some of those things are still in the design phases and we are still trying to figure out how to make that work.
We are requesting inputs from the community to help us in this effort. Kimo uses firmware config as a well defined interface for the guests to talk to the host.
So, we need to also find a ways to implement firmware config support into UKI. And then there is a question of what happens when you have multiple kernel learning
utility bundled into the same UKI, then how do you make sure that the firmware loads the right kernel image, the right in it already image, etc.
So, some of these are open questions. We will, we have not yet figured out how to do that. We just just kind of incrementally going through the process of merging small small bits.
And so, we very much appreciate your inputs and suggestions in this direction. So, talking about current status, like I said, some parts of it is already merged in mostly in around Kimo and system D. I also posted a patch earlier this week.
That kind of proposes the Kimo hypervisor interface that we planned to implement. So, in the reference section there will be links to that patch. So, please feel to have a take a look and provide us any input if you think it will be useful.
So, here is already an EFI firmware section in the UKI today. So, that part has already merged, but some of the parts that are not in place today. For example, here this matching part where particular hardware and ID entry maps to a particular EFI firmware entry, some of the bits are still working progress and we have to still merge those bits.
So, yeah, so it's reference, feel free to take a look at all the PRs and then if you have any suggestions, let us know.
Our Kimo forum talk last year in September details most of the idea and gives us more details. So, feel free to watch the recording and let us know what you think.
That's it, and questions. Yes.
That's right. So, the question is that why are we proposing to attach different formary images for different platforms in the same UKI?
So, the idea is that the UKI can contain different firmware bundles for different platforms so that way we can deploy the same UKI to different target environments, but then when you are actually running on that target environment based on the hardware, the UKI selects the right firmware for that particular so architecture.
So, that's right. I mean the kernel matching, I'm not sure if that goes to the hardware ID section that I described, but the, like potentially today you can have multiple kernel images within the same UKI.
I don't think that, like, this stuff can be multi architecture, yes, you could have different kernel.
Yeah. Stop itself. Right. I mean, it's just that the example is like, may that be rather, you know, something like different colors, for example.
Yeah. So, the UKI stop can build only for one architecture, but, you know, like, so it may not be a different completely different architecture, but you can have different kinds of bills or differences.
For example, one build supporting secure boot, and the other is there's not supposed to secure boot, so you can have like different bills for the same architect.
So, what Alex was saying is like he made my life easier. So, he's like saying that we can have one focus for different, like cloud deployments, like one for easy to or one one one for Azure, one for AWS, one for whatever, something else.
Yes.
Okay.
Yes.
So the question is that whether it's possible to have the same UKI with the same firmware that we built locally as well as
potentially if it works and if the hardware IDs are, if it generates, like basically you have to
generate, you have to make sure that the hardware IDs against which it matches are same for both
environments.
I think probably also like comment on this.
You might want to try to get the same exact cache for example, this initial measurement,
on your cloud and locally.
You may or may not actually, because these initial measurements, for example, covered the
CDI table, right?
And they describe the particular instance, right?
How many drives you have?
How many are you?
So unless it can feel exactly the same configuration locally and on the cloud, you will likely get
different measurements.
Right.
You can predict this measurement.
Right.
So even if you have different measures, they are expected by you.
So what Vitali was saying is that basically for local build, as well as for the cloud build,
we could have different measurements because they are different environments.
But the good thing is that you can predict what those measurements value would be in both
environments.
Is that right?
Thank you.
Right.
Thanks.