 Hello, my name is Łukasz Kawiłka, I'm working at Intel as Secure Engineer on my daily basis. I'm developing an awesome architecture of T-Boot project which is an OS loader for Linux that allows to use Intel TXT technology under Linux operating systems. In this presentation I want to share with you my concept of integrating UFI Secure Boot support for the T-Boot because current T-Boot version does not allow to use UFI Secure Boot together with T-Boot. Basically when you are trying to launch T-Boot when UFI Secure Boot is enabled, it is just impossible. UFI Secure Boot will not allow you to do that. Here's the agenda for today's presentation. So first we'll go through briefly what is UFI Secure Boot, what is Intel TXT, what's the differences between these two technologies. Then we'll go to description of T-Boot, the internal architecture, how it is built, what T-Boot does. Then I will tell you in details why it's impossible to use T-Boot when Secure Boot is enabled. And then I will share with you my proposed solution, how this can be fixed. Also at the end we will discuss the benefits and limitations of my proposed solution. So UFI Secure Boot is platform-independent technology. It should be available on any platforms that are UFI capable. This is static route of trust technology. That means that route of trust needs to be established at the beginning of the platform launch. And then it should be maintained up to OS level. That means we have to verify each component that is between the platform launch and the OS, and all of these components need to be trusted, need to be inside T-CV. That leads to some potential problems because the bigger T-CV, the probability of some vulnerability is higher. That's why, for example, when we recently, the researchers discovered a boothole in the boothole in Grap, that means that Grap may skip the Secure Boot verification process, that means that all Secure Boot processes for the Linux operating system is not trusted. Because one of the components that are in this boot process has vulnerabilities. Also, it's worth to mention that UFI maintains database, dbdbx, that contains lists of allowed and disallowed keys that can be used to sign each of components that are launched during the boot process. The problem here is that Microsoft owns the database, so only keys accepted by Microsoft can be added to that database. That leads to some difficulties in the open-source community to use Secure Boot, because it's not very easy task to ship system with keys outside of Microsoft. That's why when Linux is used, there is also another component called shim, that is a preloader for Grap, it maintains its own database, key database, MOK, and shim is signed by Microsoft key. Shim is very simple application, its main role is just to run next loader, but because of the simplicity, it was possible to get signed by Microsoft and then it can be verified in any UFI platform that is shipped with Microsoft keys. As shim maintains its own database, it's possible for other OS vendors to add its own keys to shim's database or embed that keys in shim build, so other Linux systems can be verified by shim. That's why in Linux UFI boot process there is another component in the boot flow that is required because, as I said, the problem with adding OS vendors key to UFI database. But the whole general idea for the Secure Boot is still the same. So, as I said, Microsoft owns key in dbdbx and it's very difficult to get Grap or Linux kernel signed by Microsoft, that's why shim was created. It's a very simple application, it's signed by Microsoft. It maintains its own key database and this key database can be used to verify the next components after the shim is loaded, the next components signatures. And this database MOK may have OS vendors keys and also end users can add its own keys to the database. And what's important fact is that shim also exposes shimlock protocol that can be used by components launched after the shim to verify signature. The shimlock protocol is added to boot services and it behaves like standard UFI Secure Boot verification mechanism. It can be used instead of it. But the difference is, of course, that it verifies the signature against MOK and not dbdbx. In Intel TXT the flow is a little bit different, so Intel TXT is DRTN solution. That's why the root of trust can be established during the boot process, not at the beginning. That means that all the components before root of trust is established are not required to be trusted. And speaking about the boothole process, the boothole process does not affect the boothole vulnerability, does not affect Intel TXT because Grap is not in Intel TXT TCP. As you can see here, there is another application that is between Grap and Linux. It is called tboot. Tboot is split into two parts. The first part called pre-MLE and the second part called MLE. Pre-MLE part is also not trusted. It is also not in TCP for Intel TXT. The main role for pre-MLE part of Tboot is to prepare environment, prepare platform for launching TXT. That means that pre-MLE part of Tboot is verifying its platform is TXT capable if all the configuration is properly set. Also, it loads its unit, which is a binary block for the TXT. And after everything is set up, it executes special CPU instruction, which is in SMX instruction set for Intel CPUs called GetSec as Enter. And from this point, MicroCode is establishing a RatovTrust. And after the RatovTrust is established, it verifies the signature of a Synod. Synod, as I said, is a binary block that is a part of Intel TXT. It is signed by Intel Ski and that's why Intel CPU U-Code can verify if a Synod is a modified and it's trusted binary file. Synod does its own verification of platform configuration, checks if everything is configured in a trusted way, if, for example, a MLE part of Tboot is inside the DMA protected region. And also applies policy that can be provided to a Synod in TPM. After all its job, the last thing that a Synod does is to measure and execute the MLE part of Tboot. So basically, a Synod is jumping back to Tboot. But now we are in the MLE part of Tboot and this part is trusted. So we are inside measured environment, we are inside trusted environment and from this point, Tboot is considered a trusted binary. In MLE part, the most important job that Tboot has to do is to measure and execute Linux kernel. So it also can compute the hashes of init-rd and also there's a possibility to provide policy to Tboot to verify if measurements are the same as expected. But it's not required. Tboot can just extend TPM PCRs with measurements and then continue to boot Linux. So Tboot is an open-source implementation of MLE component for Intel TXT. It prepares a system for entering measured environment. After that, in MLE part, it measures and verifies Linux kernel and init-rd and also it installs a hook in Linux kernel. So when Linux kernel is going to shut down process, it will not call the ACPI call to turn off the platform but instead go jump to Tboot shutdown entry so Tboot can properly tune down all the TXT environment, wipe the TPM PCRs and then wipe the memory and then shut down the platform. So when we are trying to combine UFI secure boot and Tboot, the problem that we achieved is that Tboot can't be signed like a normal UFI application. That's why when grab is trying to load Tboot, it will fail because it can't verify Tboot's signature and in UFI secure boot the verification is mandatory step. That's the main reason why we can't use Tboot when secure boot is enabled. There are also a few other things that need to be taken into consideration. First thing is that Tboot requires to use multi-boot to protocol that is protocol defined by grab. That means that Tboot can't be run without grab. Grab is also a mandatory step in the boot process when we want to use Tboot. As I said, Tboot is binary that can't be signed, it's 32-bit as binary so it can be signed using the signing mechanism for UFI and also which is important, Tboot is not aware of UFI services. So it can use services, it can verify with kernel using UFI secure boot because it's also inside the UFI services. This is not possible when using Tboot. So the first thing from the list in the previous slide was multi-boot too. That's not a big problem because recent grab versions allow to verify signature of multi-boot to kernels. So it's already working. However, still the problem is that binary should be in PE format because only PE format binary allows to add signature to the file. Grab uses Schimlack protocol, which I mentioned before when I was talking about Schim to verify this signature. That's not a problem, that's even better because then we can add our key to the MLK database. It's not required to ask Microsoft to sign Tboot binary. Now let's look how grab loads Tboot. So basically Tboot binary consists of few sections before the actual code. The first thing is ELF header, which is a mandatory part of ELF binary. In ELF header we have information about entry point, about the size of binary, about the sections in the binary and where the section should be loaded in the memory. Also there is a multi-boot to header because as I said multi-boot is a mandatory protocol for Tboot. Multi-boot too has some information to grab. For example, if FE services should be shut down before launching Tboot or not, there are also some information about also the size of the binary to be loaded. Then we have an entry point, which is a standard 32-bit entry point. After that there is a binary continuation with code and data sections. What is worth mentioning here is that multi-boot to header can also have information about entry point and size of a binary and also a target memory when the binary should be loaded. That means that all the information required for grab to load and run Tboot binary can be stored inside multi-boot to header. What is more important is that this information has higher priority than information from the ELF file. So if we add tags to multi-boot to an address tag and the entry tag, grab will take these values instead of values from ELF header to load and run Tboot. That means that in this scenario, ELF header is not necessary and can be just deleted or removed. So if ELF header can be removed, we can replace it with PE header. That's not a problem because grab will still have information about where Tboot should be loaded and what's the entry point address from multi-boot header. So adding here a PE header does not affect in the boot process. However, it allows signing tool and verification tool to sign and verify a signature of the binary. This is good because that's what we want to achieve. The problem here is that as most of the UFI platform size 64 bit, the information about binary in the PE header should also indicate that Tboot is a 64 bit application. I have tried to configure PE header as 32 bit, which is a true for the Tboot. However, the verification mechanism in the boot process will interrupt the verification process because it will detect the mismatch between the current platform and the binary. That's why PE header should indicate that Tboot is 64 bit application and then everything works. However, the problem here is that if somebody wants to run this PE binary from the directive from the UFI shell, it will get crashed because the PE header will indicate that binary 64 bit and then entry point is 32 bit. That will not work, of course. That's why I have created another entry point for Tboot, which is a 64 bit short snippet of a code that only prints any information that this binary requires to be run with my Dboot 2 and you can just run it from the UFI shell. The problem with PE header is that normally when you are building the PE binary, the PE application, this header is generated automatically by the compiler. Here in this case it's impossible. That's why I have to define it manually in the code using... it's based on the patch posted to Zen by Daniel Keeper few years ago. It just manually creates all the mandatory fields and puts it in the correct place to build the whole PE header. There's also a section table inside PE header just to cover all the Tboot binary. It's required for the signing and verification application to sign the whole binary, not only the header part. So the section table is built properly. As I said in the case that this is 64 bit application and if you are trying to run Tboot using this... if you are trying to run Tboot directly from the UFI shell you will get just the message that this binary requires to be run with Tboot too. So here are the results. We have seen that it's verifying the execute graph and graph is verifying the execute Tboot binary and Tboot. Tboot now can be signed because it's in PE format. Tboot works like before, so it's... executes, gets a center, then we are jumping to a scene. The scene is jumping back to the MLE part of Tboot from this part, from this point we are inside trusted environment for TXT and also we are in trusted environment provided by secure boot because the Tboot binary signature was verified by graph. However, as I said, Tboot does not allow to... does not aware of UFI services. That's why it can't verify Linux signature. There's also another problem here. As in it requires to call exit boot services before launching it. So even if Tboot can access... can access EFI services from this point in MLE part it will be impossible because exit boot services will be run before and all boot services will not be available here. That's why from this point we are finishing the secure boot chain and only we are measuring and executing Linux in TXT manner. It's still better than before because now it is possible to enable secure boot at run TXT. However, there are some missing points because our goal is to provide end-to-end trusted chain in new UFI secure boot and now we are breaking it on the Tboot application. So how can we verify Linux kernel signature when we are using Tboot? We know that kernel signature can be verified using EFI-Shymer protocol. Graph can make keep boot services available when loading multi-boot kernel. However, the problem is still that as I said Tboot is not aware of EFI services at all. The second problem is that EFI services are mostly 64-bit because on most modern platform EFI is a 64-bit service and Tboot is 32-bit application and we know that it's impossible to combine these two things. But as we know, we can add a 64-bit entry to Tboot like we did before and this entry can verify Linux kernel with Shimlock protocol which is exposed by Shim. Then it can call exit boot services because this is required for Ascended and we can't do that from 32-bit Tboot part and then it can switch CPU to 32-bit protected mode and then jump to standard 32-bit entry. This is the idea but this idea requires some more changes in structure of Tboot binary. Here is the final structure. We have P header like before we have multi-boot to header like before. However, now multi-boot to entry tag does not point to 32-bit entry like before but it points to 64-bit entry. Also, there is a special tag in multi-boot to header that instructs GRUB to not call exit boot services before launching Tboot. That allows us to access Feeboot services from the 64-bit entry point in Tboot. In 64-bit entry we can use Shimlock protocol to verify Linux kernel then we can call exit boot services and jump to 32-bit entry switch to 32-bit protected mode switch CPU to 32-bit protected mode and then jump to 32-bit entry standard entry point for Tboot. Then we continue executing like before there's no differences. Here is the final result. We have secure boot enabled so Shim is verifying GRUB signature also Shim installs its Shimlock protocol to Feeboot services then GRUB is loading Tboot using multi-boot protocol but as I said multi-boot allows to verify secure boot signature so first Tboot verifies that signature then launches Tboot using information from multi-boot to header so it jumps to 64-bit entry point of Tboot and then Tboot from this primary part because the 64-bit entry point will be inside the primary part this entry point will only verify Linux signature nothing more and then it will switch to 32-bit continue the execution of Tboot like before then Tboot will as like before go to SCNIT SCNIT will establish the trusted environment for Intel TXT and then SCNIT will jump back to the primary part of Tboot from this point everything is launched like in normal flow so Tboot is measuring and extending PCRs with measurements of Linux kernel and in interd and then executing Linux kernel as I said before Linux kernel signature is verified before in primary part by 64-bit entry in Tboot and also Linux is trusted by TXT because its measurements are extended to TPM PCRs so now we have the situation where trusted chain for secure boot is keep from the beginning up to the OS and also Intel TXT is used as a secondary technology that give us more security during the boot process ok so let's talk about benefits and limitations so the most obvious benefits that we are adding another layer of verification also secure boot allows to verify components that are not covered by TXT because as I said Grap and everything before Grap so BIOS and any other preloader before Grap like Shim is not inside Intel TXT TCB is not verified by Intel TXT also some customers may have a requirement to have secure boot enabled and also want to use Intel TXT as another level of verification I've got some I have some discussion with few customers and indeed the problem that when they can't use Intel TXT even they won't because that requires turn of the secure boot the problem here the biggest problem here is that boot services need to be terminated before get secure center that means that Linux kernel does not have access to boot services I don't see any solution for that because accessing boot services inside from the component that is inside Intel TXT TCB means that Intel TXT TCB should be expanded to UFI that means that the primary benefit of using Intel TXT is that its TCB is very small and only few components few mandatory components are inside this TCB this benefit is not valid if you want to use boot services from Linux kernel so that's the biggest limitation and we just have to live with it there is no possibility to do any work around for that so the current development status is that I have prepared a POC with all these changes that I have described in this presentation the POC is submitted to the UPSC repository of Tboot on the south forge it is put to branch 2.x because the overall idea is to bump version of Tboot current latest version is 1.9.12 and version that supports UFI secure boot will begin with 2 so that's why the branches I have created another branch for that I am waiting for the feedback from community about the opinion if this solution is useful for them if something is missing and if I collect feedback also if when this solution goes to validation after that I will merge it into default branch and then bump the whole Tboot version to 2.0.0 thank you for listening to this presentation I am open to answer any questions also if there are some other thoughts after this summit please ask me using the Tboot mailing list I am active there so if there are some thoughts some ideas please send just the Tboot mailing list thank you