 Although I'm talking about T today, but not that kind of beverage. This is my opening slide from the talk I gave last year in Berlin. It was about trusted boot. It was easy because I just added this. So the talk was about how to boot your Linux system. It was an IMX6 trusted into overall bootloader kernel in the root file system. And to protect your system against offline attacks. That was last year. And this year, we added this opti in the middle, where you can, this is what this talk is about. Yeah, overview. I will talk about the ARM architecture a bit. The ARM trust zone, trusted execution environments, and certain implementation of this, the open portable trusted execution environment, which is opti. So the question, what is a T trusted execution environment for short? It's a method or an API definition to split your application into two parts. One part that runs normal under Linux, and another part that runs in a different sort of isolated environment. Then we are talking about a trusted execution environment. This application in the trusted execution environment, it can be in a different chip, or in a co-processor, or as we will see on the same ARM chip using a technology called trust zone on ARM. In a trusted execution environment, you have two sorts of operating systems. One, your rich OS, or normal OS, Linux, Windows, maybe Android, whatever. And in parallel to this, you have the trusted execution environment, which only executes certain stuff that is signed. This is a limited sandbox, different processor, same processor, and with some isolation in between, and on which this is opti, this uses the hardware assisted sandbox from ARM. So why do we do this? On one hand, on one side, we have the rich OS like Linux. It offers a great functionality, but Linux systems are often targeted by hackers, or malware, or simply code load and rich attack service, so the security of a rich OS is quite low. On the other side, you have the secure element that they call it in the security role, like a chip card, a smart card. This is very limited functionality, usually low processing power, but it has very great security. And the trusted execution environment is something in between. It has medium functionality and much more security compared to a rich operating system like Linux. A trusted execution environment should provide much memory, high processing power, but it's still isolated and protected against attacks from the outside. So let's have a look at the ARM architecture as it's normally used. You have an ARM SoC at the bottom here, in the supervisor mode, the privileged level, their list operating system, Linux for us, and in the untriveled user space, there are other applications. So this kernel has control over the hardware and isolates the apps against each other. This is how a normal traditional ARM system looks like. And then ARM added with the ARM 11 architecture and the Cortexes, ARM v7 and so on. And they added this normal world. This is not an edit, this is the original view. Normal world, as we know it, it's integral. So a completely separated environment, they added the secure world. In the secure world, there exists also the supervisor mode, so the privileged mode, and the user mode, untriveled. And special state, the secure monitor has been added that's used to switch between these two. Excuse me. Yeah? It's impossible to hear how the microphone. Oh yeah, sure. So the trust on an ARM. It's not a crypto-co-processor, it's isolation done by the processor itself to divide the processor into two parts, the normal world and the secure world. One is trusted, of course, the secure world, and one is not. This is a normal world. As I told you, the privileged levels, privileged, unprivileged, we have these. So the secure world and normal world and the privileged level, they are orthogonal to each other. So we can run an operating system with privileged mode and unprivileged mode in parallel to the normal world. The partitioning is done by the processor itself, so it's hardware-assisted. And the way you can get from one mode into the other mode is strictly limited. It's only via the secure monitor are possible. So the trust zone provides a complete virtual system for secure computing. So the processor is the hardware and software is split into two worlds, the normal world and the secure world. And the way to get from one to another is quite limited. The trust zone in detail looks like this. Normal world, secure world. And you can partition the individual parts of the system. For example, in this example here, the normal world has the MMC, the GPU, and the UART. And the secure world has the RTC, the GPOs, and the I2C. You can configure this from the secure world. It has usual access to all peripherals on the system. And you can take it away from the normal world so that it's only limited. Further, you can partition the RAM that the secure stuff lives in one partition of the RAM and the normal stuff has access to a different part. And you can configure shared memory regions. There is a special register where you have this non-secure bit. It's a secure configuration register. When this non-secure bit is one, you are in the normal world. And if it's zero, you are in the secure world. Some registers are banked. This means there are two register sets, one for the normal world, for example, U. So the MMU has two sets on the system, one normal, one for the end-up controller. OK, sorry. So some registers are banked. Some peripherals like the MMU and the interrupt controller said each system has a different look on it and can configure it. So the system designer, when you are using the trust zone, can partition the software and the hardware between both systems. And how these peripherals can be switched between the worlds purely depends on what the SOC implementer had done. This is not specified by ARM. It's up to the SOC vendor. Some controllers, some peripherals support the secure world they know from which world they are called and some not. So this might be a problem. It purely depends how good the trust zone is on the peripherals, what your system designer, your SOC designer had made. This is just, yeah. So the trust zone is a security extension to the ARM processors. It's supported since Army 11. But I think no one is using it anymore. It's on the Cortex-A series, like the 32-bit and 64-bit. And new implementation was added for the microcontrollers. As I said, you have a system-wide hardware isolation, SRAM, DRAM, CPU configuration registers, and some peripherals. And the last sentence you have to keep in mind, the practical usefulness really depends on what your SOC designer has implemented. How to switch between those worlds? So it's a simple diagram like this. During reset, your system comes up in secure state. Then you're in secure state. And there are, as I said, only a limited number of ways to get from one state, from one world to another. To go into the secure world, it's surely hardware-controlled, because you don't want to do something on your Linux kernel. It may be hacked. You don't want to enter the secure world just by flicking some register. So from the secure world to from the non-secure to secure, you go by reset, obviously. What the normal process is, you do a secure monitor call. It's a special assembler instruction. It's analog to like a supervisor call when the user space calls the kernel. With a secure monitor call, the kernel can call the secure monitor and then switch to secure world. So it's a tightly defined, just one assembler instruction to switch between both worlds. And as I said earlier, you can configure your interrupt controller where your IRQs, FIQs show up. From secure to non-secure, it's done by software. Of course, you're insecure. You're trusted. You can toggle this non-secure bit to a return from exception. It's analog to return from interrupt. And then you switch the worlds. Now that we have this technology established, the trust zone, we have a look at Opti that uses this trust zone. So Opti is a trusted execution environment, which is not based on a core processor design or extra controller or secure elements chip. Now it realizes a trusted execution environment by using the trust zone that I just explained. Opti started some years ago as a closed source project by some mobile vendors, chip companies, some telco providers. Since 2015, it was open sourced as VSD license. And it's maintained by Baldy Narrow now, and they own it. And in 2017, so earlier this year with 2.14, the kernel driver to support calling from the Linux kernel into the secure monitor. So to switch into the secure world has been merged to the kernel. And after we noticed this, we had a look at it and played a bit with Opti. Yeah, as I said, it's based on a trust zone to provide the isolation. And it runs on about 20 ARM platforms, 32-bit Army 7 and 64-bit Army 8 processors. This is how Opti makes use of the trust zone. We have this secure monitor here in the middle. It's used to switch between both worlds. So with Opti, you want to write a Linux application and put a certain part into your trusted execution environment this year. So the trusted execution environment defines an API. It's standardized by a global platform. It's this T internal API, how the trusted applications can communicate their C library, their system codes are defined here. And your native application can interact with the trusted application can load it over the T client API, which is also defined by a global platform. Maybe here's a wrapper API that makes us a little bit more comfortable. So these are the user-facing parts. Opti consists of three parts. The Linux user space stuff, Opti client. It's a good repository called this user space stuff implements this global platform API and a helper program because if you want to access the file system for secure storage, so you want to write trusted encrypted stuff onto your file system, it's quite hard to do this from inside the kernel. So this goes over here through the driver into the user space and then user space can write it over a standard Linux mechanism to some storage. Then we have this T driver subsystem which consists of a generic T part and an Opti part. And this has been merged to Linux in 4.12. This should be T agnostic. So you can have the same API here and the same T driver and a different implementation of a T. This is what the idea behind it, because there are several implementations out of three T drivers and T applicants out there, I've heard, and Leonardo mainline this to get everyone on board using the same T driver and the same interface to get your supplicant running. And the Opti OS itself, so the stuff that runs in the secure world is Opti OS. This is a T internal stuff, the C library, so system called, so to say, the API and the secure monitor here. For ARM v7, this is implemented by Opti on ARM v8. I think it's implemented by ARM trusted firmware, so it depends a bit on your actual system. But the idea behind is you have here the same API for your trusted stuff and the API for your user space stuff so that you are independent of the underlying implementation. Because Opti consists of three parts. This is basically just what I've told on the other slide. A normal world user space, the T client library and the supplicant for file system access, basically. In the kernel, you have the T driver and the Opti driver. And in the secure world, you have the Opti OS. And of course, you can only load trusted and signed applications into your trust zone. This is an example of how we implemented the booting of the Opti enabled system on an 32-bit IM-X6. As a system comes up in secure state, you have to get your trust anchor into your CPU. And this is what my last talk at ELCE was about. Just to recap, on the IM-X6, you have your SOC and you have fuses burned into your SOC. And the fuses are used to see if your bootloader blob is correctly signed. So this is a trust anchor from the fuses to the big bootloader blob which holds the pub key. And the signature here is over the bootloader. And then you know when this whole system works, which is done by the ROM codes, you have a bootloader, which has been signed for your system. So you have a running bootloader, which you can trust. And in this bootloader, we have compiled into the binary of the Opti. And the Opti has the next step for the trust chain, has another pub key. So after the system has booted into the bootloader, we have a bootloader running in the secure world. And we have an Opti and we've established a trust chain and then we can boot the Opti. This is how it looks like. Secure world here, reset, then the ROM code runs. We load and check the bootloader. The bootloader starts up. In our example, we have used barebox. Then the bootloader loads the T, which is already compiled into the bootloader. It loads the kernel, the device tree, the init RD, which are all in a single image, which are signed. And then normally the bootloader would just jump into the kernel and the bootloader is done. But here we want to boot the Opti. So we jump into the Opti. And the Opti has been set up to boot the kernel. So you just squeeze the Opti between the bootloader and the kernel. And the Opti will start, initialize, then have a look at the parameters. And notice, oh, there's a kernel. There's the device tree. There's the init RD. Boots the kernel, which has been loaded by the bootloader into the RAM. Kernel runs, starts up. Then your applications run. And then when an application wants to trigger a service from the trust zone, the user space does a call. It triggers down the stack, secure world call, into the Opti. The Opti performs the service, returns from exception, into the kernel, back into the user space. This is how the system comes up and runs. So this is how you get your system running. What you can do with Opti, at the moment, you have an API for secure storage. You can access the internet via UDP, TCP, and TLS. And I've seen some demo applications and a test suite for the global API platform. And I think it's now up to us to implement stuff on there. Please don't do DRM. Better implement some interesting stuff like attach your support for known private key storages to it, like the kernel private key storage or your OpenGPG or SSH, or even implement a TPM solution that's based on Opti. Yeah, what do I want to have from SOC Windows? You need more SRAM, as you see nowadays on processors. Modern R, the iMX6 has about, I think, half a megabyte of SRAM or even less. It's used by the graphics guys. And you have to battle with them if you want to get your Opti running in this. And a point of critique from my side regarding the trust zone. Opti itself just defines the interfaces to access the internet, IP, and so on, and secure storage. But in general, with trust zone, it's possible that you can put your hardware, your GPIOs, your Ethernet controller, whatever your GPU, even into your trust zone. And then, yeah, you should trust that. Today's system of chips are, I think, not designed for this yet, because what happens if you turn off the clock from the Ethernet controller from your Linux system, and the Ethernet controller belongs to the trusted execution environment? Doesn't work anymore. What should you do? Should you move your clock controller stuff from Linux to the trust zone? Maybe then you have to implement some message box system. Please turn on that clock for me, or it's complicated. And you even cannot just copy the code from Linux to your Opti, because Opti has a different license. It's BSD license, and it's not compatible with Linux, so it's complicated. What do you do with graphics drivers? On iMix 6, we just have a fully open source tech line. This is GPL2 license. It's not compatible with Opti. Problem. Let's see what's coming up next. Maybe someone uses it this way. Maybe some people are just doing computation, storage, TPM stuff in the Opti. Having looking at the code from the Opti build system feels a little bit maybe Android-centric, not Linux-centric. It doesn't obey the Linux file system standards by default. I think maybe it's mostly used by Android for now. I think they should make more use of the device tree, which we have in Linux. I've seen a talk or a lots of other sessions about making more use of it, so I think it's a way to go. Because if you have a look at the platform definitions, it's quite some depth in there. If the RAM start is not defined, then I define it to here. And maybe I'm not running in the RAM. Maybe I'm running in the SRAM, which is different. So maybe switch to a K-config or something, or get rid of this and load everything from a device tree. Yeah, this is it. Just a summary, T is a trusted execution environment. Set of APIs to split your application into two parts. Opti makes use of the trust zone. Trust zone is a security extension for ARM to split your processor into two parts, secure world, non-secure world. And the usefulness depends on your suck design, really. Yes, Opti implements a T on the ARM trust zone. Thank you. Any more questions? Yeah, do we have a mic? In a previous slide, you wrote that Opti part was scheduled from the non-secure world. How do you ensure that there is no denial of service? I think this is not handled yet. So I've seen some sessions about, yeah, we should definitely get a fuzzer and fuzzers through scores and IO controls and test it if they are really, really safe. As I said earlier, if you have access to the kernel, you can just turn down the power of some peripherals as they are used by the trust zone. So it definitely has to take care about the service. Thank you. How do you deal with the GPL3 compliance in this case? I mean, when you are using the Opti into your system, are you creating a sort of a typoization of the system so you need to ensure that you are doing everything correctly? So Linux is GPL2 license and Opti is BSD licensed. Yes, but you can burn different fuses or you can into your boot loader. You can not just burn fuses for one pub key, but for different ones. And then you can maybe have an open configuration that you give to your customers that they can put your system. But maybe it's not working. Maybe the proprietary application you are running is not working because it's seasonal. It's not booted from the right key. We have not used Opti yet, but we have used or implemented this secure boot stuff without Opti for customers of us. And yes, they have no GPL3 parts in there. They are very eager about this. Yeah. Any more questions? You mentioned the fuzzing of the API. If the API or if I get code execution in the secure zone then the trusted keys in the example of a TPM implementation is broken. The keys, if I implement the TPM, can I extract the keys if I get code execution? Probably yes, I think so. If you can manage to break in there and execute some code, you probably, but for now, the Opti is running on most systems in DRUM anyway. So you can load everything, boot everything, freeze down your ROM, or analyze it when it's running. So this is why you need more SRAM to have everything in the internal chip, internal ROM. So it's more complicated. I think they even now implemented the paging so that you can swap out stuff from your SRAM to your DRUM, but encrypt it on the way with AES. But I think this makes everything more complicated even. I'm not sure if this definitely blows up your code base. And a colleague of mine asks me about, Mark, do you know? Do they have some kind of formal verification done on the code? But I don't know. I'm interested also. We just had a look at the stuff and put a demo system together after Opti was merged with the Linux kernel. Yeah, question? I'm interested on the aspect of secure storage and how it is implemented in Opti FE. So you brought up this example of IMX6. And probably, as you know, IMX6 also offers hardware-based secure storage mechanism, so each IMX CPU is coming with its own master key, which allows you to use a crypto engine to encrypt blobs of data. They call it black and red blobs. Is Opti FE implementation using this mechanism on IMX or is it just software-based? As far as I know, it's just software-based. And they take different parts, your UID for your application, some nonces, hash it together, some HMAX. And this is how they derive their keys. So I think it's similar to your trust or to the red blobs from the IMX. But I think you have to implement a callback for this that you can get a pair device ID from your hardware in the secure side. So I'm not aware that they are using the Karm, so the crypto engine of the IMX6. We would love to do so for some other projects, but license problems. You cannot copy just the code from Linux to the Opti. I haven't had a look at it. Feels legit, but feeling insecurity is not really a good measure stick. Maybe comment to that question. So in Opti, the intention is that you have on the SOC some way to encrypt stuff in the secure world that the normal world cannot read. And basically on the IMX6, you would use the Karm red blob mechanism for that, but it's just not implemented. So all the normal stuff storing private keys and so on happens in software and Opti, and those then get locked to the secure world by using Karm on IMX6, but that's not implemented yet. But you have the difference between if you're just using the Karm, then your key is somewhere in the kernel, at least, available. And if you're running in Karm, if you're running in the trust zone, or using a trust zone, running Opti, and running in SRAM, your keys will not be accessible from the normal world from Linux, so if your kernel is compromised, you cannot read out the keys. Maybe you can use them to decrypt stuff, but you cannot copy your keys from your Linux system to the internet. On a multi-core system, the trusted application is executed on the core, which is doing the SMC call. Is it correct? And can I execute multiple trusted applications in parallel if I have multiple cores? So when you are calling from Linux user space to into your trusted execution environment, the trust zone just switches the view of the processor to the system, so it's the same call stack from your application to the kernel through the secure monitor into the secure world, then up into your trusted application. And the time, which is spent there, is just seen by the Linux kernel and accounted to your application. And as how they designed the driver, yes, if you have a multi-core system, you can have multiple calls from multiple cores, of course, going through the same driver through the secure monitor into your application. So if I write a T-driver, I have to ensure that I can handle multiple requests to my hardware in Opti as well. So in Opti, it's already implemented. I think it's just about the locking mechanisms are correct so that you don't pull a global lock my Opti stuff lock so that if one core is executing, so if one core is taking a global T lock here, for example, you cannot enter this application, this direction, this system call, or this API call. But it's implemented this way that you can do it for Opti. So you can have multiple cores, a call stack down here, up there executing stuff. Practical question. What do you use to encrypt and put your hashes to the files in the secure world? So if the application writes stuff, they have just an object storage, no file system. They do a write, and then here there is done the encryption and methods message authentication. Then it's transferred via the secure monitor and some shared memory into the normal world, into the kernel. Then into your supplicant. And then your supplicant just gets memory and length arguments and then writes the stuff onto your file system. So the encryption is done here. It's written down here. What you can obviously do if you have root access, you can just delete your files. I don't know what happens then. But has this interface about RDBMs, this replay resistant file storage on MMCs? Has this been merged to the kernel yet? I don't know. I think they want to attach this special storage on MMCs or EMCs here so that your supplicant can write to this memory. Glad that I started earlier. What is the status of virtualization of this whole system? Yeah, good question. I have skipped this for simplicity reasons. The virtualization, if you, what's missing in here? So this is user mode, kernel mode. And on ARM v7 and newer, you have the PL3, the hypervisor in between here. So you can just run a hypervisor on this and have multiple KVMs running. So it's autogonal again. On ARM v8, I think they even used the hypervisor call. This is implemented a bit differently here on ARM v8. But it's autogonal to hypervisor. If there are no more questions, I say thank you.