 Welcome to this talk about Linux Secured Integrity, a very fine boot concept for embedded systems. But before I start with the subject, I will give you a short introduction about my person. My name is Holger Dengler. I was working for Linux in Germany, a company that focused on embedded systems and real-time. And my focus area in this company is security of embedded systems. And I joined them last year. Before that, I was working for IBM in Birblingen, also with the focus on security and mainly the hardware support for the cryptographic hardware in the Linux support for the cryptographic hardware of the mainframes. So I'm a little bit familiar with the terms of security and the mechanisms there. And yeah, okay. So the agenda of this talk will be, first of all, we will start with a problem statement. Why are we sitting here and thinking about security of embedded systems? And because of the importance of the boot process in this question, we will focus on the classic boot process first and then on the verifying boot process. And after that, I give a short overview what is available today, mainly in UBoat. We did a prototype with UBoat and at this point, thanks to the UBoat team and especially the colleagues that built in the security functions. It's good stuff and it's ready to use. And yeah, thanks for that. After the status quo, we come to a short conclusion and summarize the whole stuff and give an outlook on what can be done and where is the work to do. A problem statement. Why are we talking about security? Why are we thinking about securing our systems? As the embedded systems started in the past years, they are only connected to the entity state control. So we have only a controlling system and it's connected to a machine, complex machine doing stuff directly with the machine and that's it. So the systems over the time will be extended to interact with each other and also interact with central components like a control center. So in this picture, the control unit of machine A interacts with the control unit of machine B and they exchange data and after that they also transfer the data to the control center. So for that purpose, we need to connect the control units or the embedded systems together and if you have only two or three entities that you need to connect, you can do it via direct connectivity but if you need to connect more than three entities, then it's getting complex by direct wiring and expensive, please. So more and more embedded systems are now connected to existing networks to reduce the cost of wiring the units directly with each other. So they are not only connected to existing networks, sometimes they are also connected to public networks and so it's also possible to easily access the data under control units so control units no longer only control the machine, they also collect production data and provide it to other applications so that you can monitor your machine from your desk and access the data from there. So but the more comfort you get in accessing data, the more comfort also an attacker get to attacking your control unit. So we all know that service and personal computers are subjects that can be of interest for attackers and we have some security mechanisms on our laptops and our servers to protect against such attackers and if we connect our embedded systems and control units to public networks we also have to take care about security mechanisms in these units as well. So we all know the control units run also Linux and are no longer reduced systems, they are more or less full functional computers in this time and so they can also be the goal of an attacker and yeah, if the attacker has the possibility to take over the control of the control unit then weird things can happen with the machine or they can be used otherwise. So therefore it's important that our systems are also the embedded systems, the control units, we have to take care of the integrity of these systems so that we know to each time which software or which processes are running on these systems and the important step for guaranteeing the integrity of a system is to guarantee the integrity during the boot process. If you mess up the integrity in the boot process then you are broken. So this is a very important step with respect to integrity, to a system integrity and therefore the focus of this talk is mainly about the integrity during the boot process. So during the boot process we will load the kernel and the question that we have for that step is who is the originator of the kernel, who put it on my system and this is not only a question with respect to security it may also be important questions with respect to safety. So if you think about a laser welding machine it's important which kernel is running on it, on the control unit of this machine because something can happen if the laser control is going mad. So this is the first important question. The second important question is has the kernel be modified? It's somehow similar like the first questions but a little bit different. We want to detect violations, we want to detect modifications, malicious modifications in the kernel and therefore we need a mechanism to do that and at least we want to be notified if we detect such a modification and in the next step we also need a reaction, a fine reaction if such a modification has been detected. For example we can do a fallback to a safe kernel or we can stop booting the control unit so that the machine cannot be functional anymore and so on. And last but not least main question, can this all be done without having dedicated security hardware on the system? Sometimes you have a system out in the field and you want to increase the security and therefore it is important for you to know is it possible without hardware modification for me to update my system in a way that it after the update has a higher security level or higher integrity level than before. Let us first look at the classic boot process. I think we are all familiar with boot process. In the first step we have a CPU initialization. After that the boot loader is loaded into RUM and executed or directly executed in for example NOR flash. The boot loader then will load the Linux kernel from another place in the memory and then also executed and the system starts up and we are moving from the boot process to another step. So one way to increase the integrity or to ensure the integrity in such a classic boot process is to guarantee that no one can modify boot loader and Linux kernel. That is the easiest way. We can put it in a read-only memory and then we have the guarantee that the integrity is ensured as long as no one has physical access to the system. So that is one main aspect of this talk. As long as no one has physical access to the system, life is much easier. As you have an attacker that can plug in or has direct access to the hardware, then we are in another game. So that is also not the focus on this talk today. So we are focused today only on can we reduce the damage that a remote attacker can do with my system. So put the Linux kernel in a read-only memory, then we are fine. But that is not really a good idea for systems that are connected to public systems because if I connect a system to a public network, then I have to update the kernel and the software of my unit in a regular basis because of providing all the security bugs and fixes for it and so on. So putting the Linux kernel in a read-only memory solves one problem but it causes another. It is harder to update the system and for that reason we need another mechanism to verify what we are loading and executing. So then we come to a verifying boot. We start in the same way as in the classic boot. We have a CPU initialization. After that we load and execute the bootloader. And we also load together with the bootloader a certificate or a public key. In the next step we load the Linux kernel and together with the Linux kernel and this is also a new part, the signature of the Linux kernel. So we are here using cryptography to ensure the integrity of what is loaded and what is used to verify the signature. So the bootloader then takes the public key of the certificate and verify the signature of the kernel. Check if the kernel has built the signature and checks it against what is loaded from Flash. And if the verification is successful then it starts the kernel and at this point in time we can guarantee that the kernel that is loaded is signed and given away from a person that is allowed and authorized to do that. So let me give you a short side step what is used here. If you are talking about certificates I already mentioned it. We mainly talk about a public key and if we talk about a signature, a signature is a hash that is built in this case over the kernel and then it is encrypted with a private key. That is from the same key pair then the public key in the certificate here. So who is familiar with asymmetric cryptography? Okay, the attendees there are not familiar with asymmetric cryptography. In asymmetric cryptography you can use or you can generate a key pair and with one key you can encrypt stuff and for the decrypting again, so the step back to clear text you need another key. So in this case the signature can be built by a person that holds the private key as a secret and give away only the signature. And the signature can now be verified from every person that has read access to the public key in the certificate. So that is verifying the main concept of verifying boot process and it uses the need of read-only memory. So we only need to put the boot loader and the certificate in read-only memory. The Linux kernel and the signature can be put into read-write memory. So if someone modifies the kernel then the signature won't fit to the binary of the Linux kernel so verification will go wrong. And if someone modifies the signature it's the same. And it's very hard, nearly important to modify the binary and the signature in a way that verification can be successfully processed. So that depends on which method you use to verify the stuff here and in our prototype we are using RSA for that purpose and RSA is already implemented and available in U-Boot so that was the reason why we took it. A question. Yes. Would it be possible to have the boot loader in read-write memory just as a certificate? If you put the boot loader in the read-write memory then we have another problem because the boot loader in this picture here the boot loader is doing the verification. So if you can modify remotely the boot loader then you can replace it with a boot loader that has no verification or another example is if the certificate is also in the read-write memory then you have the same problem. Someone can replace the certificate and the public key in there with its own public key and with its own private key it can sign its own kernel and then the integrity is also broken. Yes, another question. Can you talk about the trend of not being able to replace the certificate on these devices due to some other release of information that you now no longer can guarantee security on the device with this setup? Yeah, that's a problem. We actually have no concept for that because certificate or equation list handling is a little bit more complex and to have this in the boot loader may... So if you want to revoke certain certificates or key pairs then you need a certificate revocation list and proper handling of doing that and certificate revocation list handling would also be here in the read-only memory part and because no one should change their revocation list so that's the same than the certificate. So there are certain open questions, yes, but we are aware of it and then maybe we need to discuss this in the future when we having the main steps in a proper way working and then we can go to the details and check what is possible. So this is an easy or simple verifying concept that is already implemented in you would I already mentioned. So we can also think about an extended key handling. So the system key pair that we have here at the left, this is our route of our chain of trust and we can now with this key pair or the keys there can build up a chain of trust and we can put the certificate, the system certificate, this one in a read-only memory of the system and if the bootloader starts up then we add this certificate in a bootloader, so-called bootloader key ring. In the next step we can load other certificates and extract the public keys from there, this one and we verify this public keys with the signature in the certificate. So you can also sign a public key and put it together and then you have a possibility to ensure that the public key you have seen at the signing time frame. So what we have done, we took the private key, the red one is the private key and the green one are the public keys. We took the private key and sign the working public key and put it together in a certificate, in a signed certificate and put it also on our system in maybe the read-write memory and then after the bootloader loads this certificate it can also be verified before adding it to the key ring and if the verification goes wrong then we normally not add it to our key ring. And with all keys in our key ring we have now two keys in our key ring, the public key of the system key pair and the public key of the working key pair and with all of these keys we can do now the signature verification with the kernel. So all we know that the kernel is signed with the working key and therefore we took the working key from the key ring and do the verification of the kernel signature. So that could be an extension of the key handling in the bootloader. It has the possibility that you as a producer of a system can give away a key pair to a developer that he can sign its work or you can also let the developer create a key pair and then sign its keys after verifying that it's a good guy and not a bad guy. So that is an extension of the verifying boot process that is available today but it may also it may be implemented with very less effort I think. Maybe we can talk about that later because the mechanisms are the same so if I verifying a kernel binary against the signature or if I verifying a certificate and a public key string against the signature that's the same mechanism so I don't need new encryption or decryption methods it's all the same. So if now our kernel is up and running then we came to another step in the life cycle of our system. We are leaving the boot process coming to the system and now we have the guarantee that the kernel that is loaded is the one we want to be loaded and we can now use all the existing stuff in the Linux kernel to protect our system further. We can reduce or we can restrict the kernel that only signed modules for example can be loaded and so we can prevent low level kernel hacking so we can not allow another person to write a kernel device driver that accesses parts of my hardware that I do not want to that it be accessed because of safety reasons or something else. So this is one possibility to protect my system. Another important thing is to take care of the integrity of my file system and here I can use the integrity subsystems in the kernel or other mechanisms that are around there and I can also use Linux security modules like SE Linux or Tomoyo or something else. So the fact that I has the guarantee that the kernel is the one that I want to run on this system I can rely on all these mechanisms that they are working, that they are active and that they protect my system against other modifications. So the integrity subsystem EMA is part of the kernel since 3.6 maybe and it helps you to guarantee the integrity of files and hashing the file content and putting the hashing extended attributes and verifying it and so on. Normally if you talk about EMA it's most in conjunction with TPM but it's not really necessary that TPM is in the game. So as far as I know the Linux integrity measuring architecture is available since 3.6 in the kernel but I'm not sure maybe it's 3.7. We do not have it yet but we will extend our prototype and having it there and then we can give you more details about the performance. So let's come to the prototype that we built. We take standard hardware, we take standard U-boot, doing some changes mainly the DTS support for the FITEC board because it's not there already and generating a key pair doing some configuration and it's running so it's easy if all the work is done by the community. So what we now have is a prototype that uses the kernel signature verification during the boot process if the signature don't fit to the kernel then the boot process will be stopped and interrupted. So we have a system that only boots signed kernels signed by us. So the features of this prototype are the kernel verification during the boot. We have the simple key chain in this prototype so the public keys in the U-boot image and the signature is located in the kernel image and we are using RSA 2K keys and for the hashing of the kernel we are using SHA-1. Okay I have a few slides back, I forgot something to mention so let me go back to this picture. As you can see we do not have the necessity to put any private key on our system. So if you deliver the system, if you give the system away there is no secret on the system. It's all only the public keys and only the stuff you delivered. So that is very important and that's the quality of security I think. Because if any secret is on the system then an attacker has the possibility to inspect one system, extract the secret and compromise all other systems that are relying on the same secret. So that's an important quality of this verifying boot process to have here the asymmetric cryptography that gives you the possibility to deliver only the public parts of your secrets. Okay so sample configuration for that prototype. We have a signature, we have a kernel configuration. We already saw similar configuration in the talk of Simon Glass yesterday. So it's nearly the same. We have a signature here in the kernel configuration that specifies that secret and it specifies the algorithm that is used for verifying the signature and key hint or key name hint so that boot load of the built tools know which key pair is used for generating the signature or verifying the signature. So that's it. The conclusion of this talk is it is no dedicated security hardware required if we want to protect against remote attacks. As I already mentioned we are not protecting here against physical access. If we want to also include verification against modification during physical access then we need some place where we can store safely the boot loader and secrets in this case the certificate or the public key that is used to verify the signature and for that reason we must go back and use a TPM for that reason. But it's the same process so we can combine the same process with a security hardware if we have the possibility or if it's already on the system and we're getting a better quality or higher quality integrity for our system. The concept is adaptable to your needs so if you need more if you need an extended key handling with a key chain then it's possible with small changes to cover this as well and it's extendable as I already said with TPM using a TPM or other security hardware. Maybe you can also think about a one-time programmable memory if you put such an entity on your system then you can get the certificate or public key from there and then you're at the same level then using a TPM. One important item here or thing is this concept is completely reviewable. You have the possibility to review and guarantee that there is no backdoor implemented in this concept. That's a possibility that if you have security hardware in the game it's mostly not possible for you so you won't get the construction details of a hardware chip that guarantees you the security. As I already mentioned we have no secrets on our system so if someone takes a system and doing some investigation he is not able to extract any secrets that helps him to attack other systems that rely on the same secrets. And last but not least it's already there, use it. So if you have a system that uses UBoat in your version then try it and be happy with it. It helps you to increase your security level of your system. That's from my side. Do you have questions? Yeah, what sort of effect does it have on you? Yeah, so verifying the signature you have to hash the curdle. So if you're using the verification you have two possibilities. So one possibility is to directly checking the curdle and verifying the signature of the curdle but you can also use another possibility. You can configure that curdle with a certain hash is required for that configuration and then sign the configuration and that is much faster. But in our prototype we're doing the simple thing and verifying the curdle and this depends on how big the curdle is and the curdle size and how fast your process is. In our prototype it took 50 seconds, sorry, half of a second. So you have to create an hash of it and then you can sign the hash to fast verify it with the only part of it. I mean, if the curdle is made in this configuration you can copy it second on the curdle and you end up with a security only recoup. Or if you really want a completely insecure system because someone completely destroys your system. So I think it's better to have what the important things have in really the only way of designing even with the use of different solutions. So the question or your comment is that not only the boot process needs to be verified and that's true. The boot process is one step and it's the first step. But we also need to guarantee that the configuration of the bootloader and the file system and other parts of the systems are also secured or the integrity is guaranteed for these parts as well. So your system is unsecured again and it's secured in RAM. Yeah, that's right. The question was if we only secure one part of the system, other parts can be modified or damaged. And so it's possible to having an unsecured system in the end, although the boot process, for example, is verified. So it's important that all the steps you're taking care of, that all these steps fit together. And yeah, and there are no holes in between. So because an attacker normally find those holes and go there and then you are broken again. So it's one step. So the boot process, it's one step in the game, but it's an important one. And therefore try it out, use it and getting familiar with it. I think it's worth to take care about this step a little bit more. Yes? Is there any reason here? The question was is it possible to put the bootloader in a read-write section and having some process in place that verifies the update of this region? And yes, it's possible, but it's also a little bit tricky. It's restricted very carefully that no one can access and write access this area in memory. Yeah. Most of the root kits for Android phones are based on in-control and overwriting your bootloader. That's the primary exploit to get root on an Android phone. Yeah, another possibility is to use a dip switch in your write-enable line of the memory area. And so to update the bootloader you need to have physical access. So I think the sequence of updating the bootloader is not so often than updating the kernel. So sending out service personnel to the machine every two years. And if necessary update the bootloader, that's acceptable for most people, maybe. Yeah. Yeah, if you have other requirements, then you need other mechanisms. For example, if you have that requirement, then it may be a possibility for you to store the keys, the secrets in your TPM, for example. Use the mechanisms there. That may also be a possibility. Okay, so I think we are done with the time. Thank you for your attention.