 Good afternoon everyone. It's at the end of the conference. Thank you for having the graciousness to come and listen to me for half an hour My name is Grant Likley. I am I'm a Linux engineer working for ARM in the open-source office system architecture team And so in system architecture I end up looking at a lot of different areas of the technology of what we need out of the ecosystem and One particular area that I end up spending a lot of time looking at is boot So I mean today I want to talk about UEFI secure boot on U-boot, which I imagine a lot of people saw that title about what is this UEFI U-boot? These are two very different things So this is something that is going to actually make when we're doing embedded systems is going to remove a lot of the variability and Problems that we haven't embedded that it is it's going to become important over the next few years for embedded systems So I just want to go over what this is Now since I'm talking about UEFI What I've discovered is I have to most of the time I have to start with with some level settings It's just some basic understanding of the terminology and what it is that we're talking about because we've got two very different Ecosystems when it talk when we talk about firmware. We've got what we've done in the embedded space with U-boot and Or other bootloaders as similar that we've got our own Process ways that we've got the project set up the way that we boot things the way that we get into Linux and all that and then there's the PC world and the PC world had bias and then that gave way to UEFI which was Or EFI which then became UEFI as an open standard But they've got there's a different set of practices that go along with that now In what we're what in terms of architecture There's actually a whole lot of value in trying to kind of bring those two worlds together And there's been a lot of work done in on that put on that in particular over the last few years But I need to define some things so first of all when I talk about UEFI It's really important to know that UEFI is not a firmware project It is not an implementation. It is not what is running on your laptops UEFI is a specification Right it defines ABI's and behaviors for firmware. That's it Most of the time when you say someone's you know, I'm running UEFI What they're usually talking about is they're talking about Tiana core or EDK to and if you can go you can go on to the Tiana core project website on on github and you can find the UEFI reference Implementation called Tiana core and that's most of the firmware on PCs That's derived in some way from the Tiana core project and as UEFI has been brought up on things like ARM servers We've used the Tiana Tiana core project to bring that up because it is a full complete implementation of the UEFI specification and It has all of the same characteristics as on the x86 world as so on the armworld. We've we've just bring all those things over However as it's only a specification, it's not the only implementation. There are other implementations that are not related to Tiana core I don't think any of them are high-profile at all and I don't think they're probably not worth talking about here But you boot actually happens to be yet another UEFI implementation It's and this is something that first got merged into you boot a couple of years ago And it's actually in quite active use So it's also I will come back to some of that But I should also talk about why we're even talking about UEFI for the embedded world What I find every most conversations I have about embedded Linux, especially when we're talking about bring up has some form of Bringing up getting a different each arm platform booted is hard Every single one of the every single embedded platform not just arm using you boot There's always a little variance. There's little the scripts are slightly different You need to do something special to get it to boot. You need to have the right bits and bits and pieces Because what what UEFI does because it's a specification it actually goes ahead and defines specific behaviors in a particular way of this is this is one of the way to go through the boot scenario Not because it is the one true way to do things but because it is by agreeing on a common way of booting the system It means we've got interoperability between between platforms in embedded We haven't had the economic drivers to do that right we go to do a product you bring up a board You do the things that you need to To run on that board, but it becomes painful for anyone who is trying to support more than one thing So if you go and talk to Linux distributions, they will be the first ones to bring up that it is Not viable for them to support a large number of embedded Single board computers because they have to produce a different image for every single one So what UEFI does is it actually brings a set of standards that are already written And as it says standards that we already have all the code that works with that in the in the Linux space So that you're able to build an image distros are able to build images that are supported by firmware from up with a very diverse set of platforms It means we've got the same we can actually adopt the same boot flow on an embedded and the server market With very little cost to ourselves because all this code is already written It gives us more functionality The one thing is the boot process But another thing that UEFI brings to the table is it defines a set of API's for services So that if you need to go and do something custom or if you need to write a little bit of pre-boot code Or you just want to display a nice graphical menu There is an API and there's a runtime available that allows you to write an application that is portable and will run on any compliance UEFI UEFI firmware and then the firmware is able to provide hooks into all the drivers that it already has For instance into the network stack or the the driver Or the storage stack The OS is of course love this because that means they can just do a single image They don't the end users is good for the end user and when I say end users in embedded I'm talking about the people who are going from the next stage of I've got a platform that boosts Linux Now I need to get my application stack up and running on it You're it's able to extract a lot of the device specific details that we've That previously you've needed to know such as you know, what's your flash partition map right by having a spec and A set of agreements on how to do this we can sidestep a lot of those things and it means that when we're bringing up embedded products We don't need to spend as much time doing this fiddly bits Now we've already known this in the you boot community, right? We've already if you go and look at the history There's things like distra boot and distra boot was already steps down this path Because what distra boot did is the same thing as I said, let's have Common behavior and distra boot went and it looked on disk and it would load the same Configuration file that's used by grub so that we can make the same same decisions and distros can still update This is the next steps down that road rather than just trying to emulate or trying to be somewhat compatible By implementing UEFI we can be actually compatible and actually use the same processes So what does you if I bring? It does a number of things first thing it does is it defines an executable format and an API so the Executable front. It's not rocket science as Pecoff is the format why Pecoff well that was that what was Chosen early on It does the job it brings a standard API so that when you have a UEFI binary or an application that runs on UEFI You've got access to environmental variables. You've got access to storage. You've direct access to storage You also got access to file systems. You've got access to network services and IP stack and IP And services like IPXE Applications can then be portable and don't need any knowledge of hardware And so this all and you know we've got that place where we can run bare mental applications whether it be you want to display a menu or One of the examples that came up is a set top box and a set top box That's that's managed by a network operator might need as part of its boot flow that when it comes up It needs to go and run a little bit of code to do do I need to do some policy updates on my box? And so it can do that in the pre boot environment and know whether it needs to go out to the network to fetch a new Kernel or a fail-safe kernel Before then jumping back into the normal boot flow and the UEFI a bi because it's standard It has all the hooks that are needed to go and do that oh Well, I'll come back to runtime services on that because I want to say one more thing on this All of the things that I've talked about here again are not new You would already has all the drivers for for file systems. It's already got the drivers for networking Applications what it does do though is it wires it in in a common a bi and that's the that's the only difference so if you go and you take a look at the difference between new boot without UEFI and With UEFI the delta encodes in binary size is actually very small Which I had intended to go and get that calculation just before this presentation and then forgot so I apologize for that But you can ask me about that later the other thing that UEFI defines which is Probably the most controversial part of of UEFI particularly for those of us in the in the Linux space is UEFI defines an API for runtime services Right, so I mean the primary job of firmware, of course is we want to get into the operating system Run to boot time services are great when you want to run that bare metal application But really our goal is is we want to get over to the OS Once we're in the OS, especially those of us, you know Linux developers We want control over the box we want control over the entire exception level that Linux runs at and UEFI comes along and it says hey, I've got some code that you can run while the OS is running and Immediately as kernel engineer the kernel engineers go We don't want firmware still running and possibly doing naughty things to Memory while while our kernel is running. We've been bitten by that many times before a firmware going off and doing things that That we're not happy with So I'm going to defend UEFI runtime services for a bit The runtime services that are defined by UEFI is actually quite sensible So rather than there is a blob a block that can go off and run on its own with no Control over the operating system. What UEFI does is it creates? It puts a set of callbacks Into a region of memory. It tells the OS about this region of memory It gives the OS a hook for the OS to say Here's the memory map to run once you switch over to the virtual memory map And so that the OS then if it needs to call into a service for firmware The OS has the control has control over the runtime environment of that and it's able to sandbox it And it's even able to inspect what that code what that firmware code is doing When it gets called and the other thing that's sensible about it is it's actually really limited The only things that are put into runtime services are things that the operating system really actually does need the Firmware to go off and do for it such as if you want to change the boot flow While you're in the OS. It's a standard API for the OS to go Modify this boot variable so that the next time we reboot it goes and runs a different binary Or here's an update to firmware that I've gotten off of the network Capsule update firmware can take that firmware can then verify the signature and then apply it or Get the system set up to apply that change before the next time around so it's things that are sensible And it's things that are limited and there's there's not a danger of UEFI kind of becoming this monster that takes over the system It is quite constrained and there's a it quite aggressively tries Encourages the firmware implementation to turn things off And of course with U-boot with mainline U-boot I mean if the U-boot sensibility we definitely want to turn all that stuff off So the implementation that's in U-boot is doing the right things and not leaving a whole bunch of resident stuff And also runtime services are entirely optional if the operating system says no, I don't care I don't want your runtime services. It can just reclaim that memory and go off and do its own thing It doesn't have to preserve any of that So in U-boot specifically for UEFI U-boot has native support for the UEFI ABI and the most important protocols that UEFI defines It's in mainline. In fact, you can enable it for just about any U-boot platform Certainly on ARM 32-bit and 64-bit. I believe x86 I know there's some other platforms, but I wouldn't be able to list them for you It's OpenSUSA and Fedora for instance for all of their single board computer support they use this Right, they still have to do custom images for each individual board because the firmware how you actually get firmware onto the board is still a problem But it's this is their This is their abstraction layer, right? So you you get into U-boot once it's in U-boot Then you've got all the mechanism of going to grub and it can do the regular updates of updating the kernel So Fedora and OpenSUSA have been a big supporter of this There's a project called EBBR, which is documenting the standards that are required for distros to boot on embedded systems And so EBBR is embedded base boot requirements And if you're familiar with the ARM server space, it's similar to the SPSA SBBR standards And so wherever possible we use the same interfaces between those two so that we've got one ecosystem of software on Both ARM or on server and embedded And it implements the runtime services right now it's mostly empty stubs, but there's variable services that are There's some patches to add variable services at runtime by caching and there's some work being done to actually how do you store? How do you handle storage of or accessing storage devices when the kernel actually owns them? But I don't need to get into too much detail of that. You can ask me about that later So Demo this is just proving that this all works what I did before I came here is I went on to the OpenSUSA website I downloaded the latest tumbleweed. I it was the generic image not targeted in any specific System this is the image that would boot on basically any ARM server machine. I took mainline QMU Actually, not mainline QMU packaged on Debian I've compiled U-boot yesterday, and I just ran it with BIOS U-boot.bin And this is it So you can see this standard U-boot slash screen and The best thing about this is this demo is incredibly boring Really all that happens here is you see the UEFI boot It goes through the UEFI boot sequence it finds the disk it finds the boot AA64.EFI binary in the UEFI boot directory it runs it and Grubb comes up If I let this fall through it boot right into the operating system I just want to show that Grubb was actual functional Loading an ARD loading kernel get a few messages from the Linux kernels EFI stub Wait about 20 seconds Well, I talk and fill the air with sound while I'm waiting for this to continue And it's taking longer than what I did it's 10 minutes ago There we go Right, so I didn't do anything special here. This is just mainline U-boot I just cloned the tree and built it and It just worked And this is with this is with an ARM virtual system, but this is through U-boot This is not using Tiana core or any of the the stuff that would be used on the server side Actually, I will stop this so they don't use all my battery Okay, that's the U-boots background. So I spent half my time talking just about Just what you you boot secure boot, which is why you actually came here. So secure boot with I Mean we're all talking about security now And if you're building an embedded device today, especially anything internet connected You have to be dealing with is your root of trust of how do you secure the entire boot flow? And you if I secure boot is part of that I'm not going to talk about securing the entire boot flow here I'm going to specifically talk about the secure boot portion and now you if I secure boot that is a name that is that is what booting is actually what secure boot is called in the UEFI specification and it defines a very small extension to the UEFI spec what it does is if when secure boot is enabled is Firmware will only run an EFI application if that application is signed by key that the firmware knows about It has a hierarchical verification model for delegating trust I'll get back to that in a moment And it specifically addresses the firmware firmware OS boundary, right? So this is all about it's UEFI secure boot presumes that everything from to power on of the machine until UEFI in the normal world starts running that it is all secure Once we get to the to you boot running in the normal world Ray don't run the OS then is checking for that set and it will only run whether it be a Boot menu or a special driver or some special function or the Linux kernel itself. It'll only boot ones that are signed Once it once firmware then goes and executes that the trust model also assumes that whatever was loaded Also has a trust model, right? So is this trust model everything is based on the previous stage has been secure And so therefore this next stage is secure Mm-hmm So what is here? How does here boot do this? First of all it adds the concept of secure variables? if you're I'll talk about variables again in a moment, but What UEFI implements is secure variables are variables that you can't just change like the most most variables in UEFI were insecure whereas if you had access to the Firmware configuration you can go and change anything What secure variables have is that if you're going to update a variable you have to do it with a Payload that is already signed by a key that the the firmware knows about And in particular there's four important keys There is the DBX or sorry the platform key the key exchange key DB and DBX and I'll go through these backwards So starting with the because the goal is to verify that your your applications are signed when When and that when load images calls on UEFI What it will then go and do is it will load the image it will check the signature on the image And then check if the signature or the Or the hash for that image is found in the DB variable and the DB variable is a is a database of keys keys and hashes if It finds it in DB great you get to run today. Oh Well almost then it goes and checks DBX if it finds the key or the hash in DBX Well, actually, no, you don't get to run today because the the DBX is the blacklist, right? So that allows for a mechanism where Keys can be added to the firmware That to say what is allowed to be run and then with anything is found to be found to be compromised There's a mechanism to actually then revoke keys and so if any of those things show up again or specific Images show up that are vulnerable. We've got there's a mechanism to then remove that Right. So DB and DBX controls what boots who controls DB and DBX. Well, then we get to the key exchange key Key exchange key Determines who is allowed to actually change the DB and DBX variables and then key exchange key This is just another database of keys the presumably the keys in in the in the KK are owned by owned by vendors or owned by even individuals Who are companies who are producing software and you can have multiple keys in there, right? So this allows for delegation of control if the key if you have if your key is in the key exchange key then you can Create and sign updates to DB and DBX and then to control those databases And then finally, there's the platform key and the platform key is the owner of the system Right, so the owner of the system once the platform if a platform key is set on a secure boot system That means secure boots and enabled Platform key verifies that K e K is valid K e K validates that DB is valid Dan DBX is valid DB and DBX Tell you whether or not you can boot the image right so it's hierarchical and what this allows it allows for delegation of trust So as a platform vendor you can say, you know what I trust Microsoft Red Hat and Sousa and so I'm going to put their public to keys in here Or as a developer you've got a product you can say you know what I only trust my own key I have my own key in the K e K And because it's a vertically integrated product only those images are what what will boot Because this so and then this this policy and the way this works is well defined So there's already a whole bunch of tools for actually managing these keys And the certificate authorities are already familiar with how to how to work with this right now the main secure certificate authority that will sign That will sign third parties binaries or sign third parties keys is Microsoft But there's There isn't the same for embedded systems. There's not the same You know, you don't have to use the common certificate authority. There's you can choose which keys your You trust although this is not a cut. This is not a talk about the design of the trust model on UEFI secure boot This is just how the how the interface works However, not everything is quite rosy Because it turns out that as UEFI is getting implemented in U boot There's been some impedance mismatch Right, so in U boot and if you've worked on U boot you're familiar with The variable store is an all-or-nothing thing, right? If you if you boot the system without any stored variables you get the default ones If you change any of them and then save variables anytime you do save in save environment Everything gets saved and there's no concepts of temporary variables or anything like that. It's just it all gets saved So it's an all-or-nothing thing if you want to revert back to origin original You have to kind of nuke the key store or nuke to the variable store and start from scratch You you if I has a very different set of semantics and in fact UEFI defines several different Schemes for dealing with keys or just I keep saying keys variables for dealing with variables It identifies a difference between volatile and non-volatile variables You know some variables are intended to be transient and so they will never go out to storage However, non-volatile variables always go out to storage in fact Non-volatile variables in UEFI if you change a variable whether a boot time or runtime it is expected that that variable will get Synced to storage to persistent storage immediately before the command returns Which is entirely different model from us in U boot We've already talked about secure variables If an update is attempted on a secure variable then firmware has to go and check make sure that the update has been signed and signed by key that it trusts And then runtime and boot time every variable has the flag if it's a run time if it's a boot time variable Then when you make the transition from boot time to run time UEFI forgets about those variables or when I say forget it doesn't report any of those variables Once you're running the OS. So the OS only has access to variables that are tagged as runtime The there's the impenious mismatch between U boot and UEFI has actually caused a bit of a Bit of tension on how are we actually going to solve this? So I had hoped when I proposed this talk that we were actually going to have a whole bunch of these things solved instead what I'm coming with is a list of problems that in six months from now if I They will be solved So where we're at right now is there's some patches on the mailing list to implement UEFI variable semantics It's gone back and forth between Doing a completely separate implementation of variables for UEFI from what's what's done in U boot U boot maintainers weren't so keen on that because There's a lot of there's actually a lot of value The concept of volatile variables is something that would be valuable to just normally you boot variables There is value in even if you don't have kind of a secure world for storing UEFI variables those variables you may still want to have by default in the regular environment There's Active discussion on the mailing list and hopefully there will be a resolution here in the next next couple of months, but there is Tuck a hero Akashi has been the the prime developer working on this and putting some some RFCs out there I Predict what we're going to see is the U boot variable system is going to get adapted to handle some of the UEFI semantics And we'll still have a common variable store at least that's what I'm hoping for because having a common variable store Actually has a whole bunch of advantages because it means from the U boot shell the U boot environment We still can access and manipulate the UEFI environment Turns out that the vast majority of secure boot is really easy is fairly straightforward to implement And what I mean by that is it doesn't require Access to to trust zone or to special execution environments or anything like that Firmware is perfectly capable of validating keys in the normal world To you know if you're updating the DB to test against the KEK to have the same thing all that's easy to do There's no secret stored on you on the device right so the all the the all the Key databases are public keys or hashes of images. So there's there's nothing secret there you don't need to see to Squirreled away into the secure world I'm running out of time here. I need to go quicker It's yeah, so everything is there if you can store stuff in regular storage. So it looks simple We can just do it in the normal world Unless we care about rollback protection, and this is where things get complicated because rollback protection If you're just verifying the images, that's fine But what if someone goes and is able to erase your variable store or what if someone is able to change or? manipulate what actually gets stored on disk Once out of you boots once during the OS You know the that OS could actually do whatever it wants with could potentially do whatever it wants with a key store So if you care about rollback protection and that is going to be important probably important in your security model You're going to need to have a solution that actually Once you get into the OS isolates out the the variable store to protect the secure variables One of the ways to reduce that is to use a trusted execution environment Where what we could do is delegate secure variable stores to a t application That requires backends to you with storage But what and it would require the trusted application to provide an API across the secure non-secure boundary But this is all doable and we can do this with open source Software in fact what the proposal that's out there right now and this is something that Leonardo the Leonardo edge group is working on is to reuse a piece of the Tiana core ecosystem called standalone mm, which is a Binary that runs in the secure world that can do all of the Secure storage operation it could do get set variable and handle the storage in a way that is protected from the normal world Stand alone mm is open source. So is this not like this is a closed source binary They're working on getting it running on opti if you're familiar with you can go and search what the opti Project is if you're not familiar with it So in this model you still have with On an AR 64 system where you've got the secure and non-secure parts of the system Your firmware architecture would look very much like this where you've got trusted firmware running at EL 3 you have In the secure world you have opti and opti is then running that application standalone mm to provide variable services Through to you boot that's running in EL 2 or once Linux is running be able to provide those same services So this is an art. This is one of the ways to solve that and then there's you also need to account for where where you actually store stuff where the storage is actually kept and the two Systems that have Dedicated secure storage are the easiest to work with because when you've got dedicated secure storage like the secure flash That I've got over on the secure world side You can give that to the secure world and say you know what the OS is never going to touch this Go it's yours use it and it's not going to be you can't access it any other way But there's a lot of devices that don't have that especially on embedded if you're talking about a system with that that has emmc Well, the operating system owns emmc, right? You can't go and have firmware writing and manipulating the emmc at runtime So if you've got a system like that, there is a rollback protected memory block on emmc devices, which is perfect However, you have to coordinate with the operating system or the firmware to schedule write So when an update happens you actually have to talk back to you boot or you Linux and they get Linux or you boot To perform the store for you so that there isn't collisions on transactions out to out to the device Anyway, this is the proposal that's out there right now is probably going to you don't be refined somewhat before code actually hits There are prototype patches out there for the secure storage side But you know there's still work to be done So here's the current state of things. I showed you the ufi support It's in really good shape. In fact go and play with it. It's ready to use now It's the I'm certainly encouraging. That's the direction. We should be going for for embedded systems It brings a bunch of functionality that you can use right now, and it's only going to get better Secure boot is not quite so happy yet. There are prototype secure boot patches But I haven't been able to find a recent posting of that mostly because a lot of the debate about Variable architecture and you know the RSA library where that comes from has overshadowed the secure boot work, but that code does exist and I Would expect to see that in the next couple of months hit the mailing list again I mentioned on our edge ledge is working on the the model that I just showed there and I'm just going to leave it at that. I hope I've got enough time for questions here I don't think I do but I'm going to ask anyway questions Yes, so the question is how does How does UEFI work like a you boot implementation of UEFI? How does that work with? With licensing um, I don't think there's any problem there, right? So it's it's gpl Right you boot is gpl. You if I as a specification free to implement The okay, so that there is there is an agreement if you're worried about it go sign the agreement Right go read that agreement. It is very very lightweight It is very lightweight Most I Wouldn't okay. I won't give legal advice Go to read it decide for yourself whether or not you're comfortable the you boot project is evidently comfortable I'll take one more question and then I got to get off the stage okay, so So you're saying you would already implement secure boot How is you boot secure boot different from UEFI secure boot? Okay, so you if I secure boot is a very specific thing You if I secure boot is defined in the spec when I say you if I secure boot that's a name That's a name for something that's in the specification Right, so when I say you if I secure boot you look at the spec and that tells you what it means The secure boot that's implemented in you boot the old the the other That's not you if I secure boot. That's a different scheme for verifying signatures Right, so it's just a different scheme, right? So Verifying a UEFI binary is different from verifying a you boot signed binary, right? Okay, well, thank you very much If you have any questions, I'll I'll wait outside the room