 Welcome ladies and gentlemen to my talk Opti is ready. Let's use it I will present some opti use cases and talk a bit about platform readiness within opti Let's first start with a bit about me My name is Rufen Czerwinski and I'm working for Pengatronics EK You can find me on github under the nickname E-Mantor and you can also reach me via email with the address shown on the slide I specialize in working with opti and I do a lot of system integration and testing within Pengatronics I'll start with a short overview at first I'll give an introduction to the trust zone and opti and Then I will present solved use cases The first of these is going to be secret storage using the PKCS 11 trusted application and the second solved use case is going to be a trusted platform module based on the Microsoft firmware TPM and As the last point I will talk about securing opti and how one can secure opti on the chosen platform Let's start with an overview of the trust zone Trust zone is an ARM hardware feature which is found on almost every modern ARM v7 SoC and The general idea of trust zone being that your processor is able to switch between two different worlds One of these is the normal world and the other one is the secure world The normal world will be running your standard run-of-the-mill operating system like Linux, which we prefer which we obviously prefer and The secure world is running a dumped down Execution environment, which doesn't need to be a complete operating system Which in our case presented here will be opti as seen on the picture on the right the normal world communicates with the secure world via a secure monitor and The secure monitor ensures that memory addresses are translated and that no data leaks between the two different worlds The general idea is that the secure world is not accessible from the normal world So secure world can do computations or cryptographic operations while the normal world cannot steal its secrets And the last part on the slide is access control access control for different peripherals on the SoC So serial interfaces are they able to access secure world memory SPI I square C and these have to be solved on a case-by-case basis Depending on your chosen platform Next up is opti opti is the open portable trusted execution environment and Is an implementation of the global platform trusted execution environment specifications? These specifications are open to everyone. You're free to implement them with no additional fees required and the global platform also provides a Test suite you can employ to verify that your trusted execution environment complies with the specification The idea is that you can write your trusted application Independent of the specific trusted execution environment you want to run your application on So in the end you don't need to use opti you could use another trusted execution environment which also conforms to these specifications Opti itself is a mix of the BS to BSD to and three clause licenses Depending on which source files are looked into and it also include includes cryptographic libraries like amber TLS or lip Tom crypt It's important to say that opti is an execution environment. It's not an operating system So it does not provide any scheduling or preemption if a processor runs with an opti it will Execute a certain task until the task is finished or it is sent to the normal world for example by a timer interrupt and That different concurrency models Models are per application So while writing your own applications, which should run within the trusted execution environment You can decide whether your application can be entered multiple times i.e. to for example process multiple payments in parallel or It can only be entered once for example if you want to restrict access to certain keys to only one actor at a time Let's talk a bit about opti trusted applications So the general idea is that you use a small part of your application for sensitive computation and put this into a trusted application part and the big part of your application is still running within your Linux operating system so you can take make use of the rich environment available there make use of the available libraries and everything else Thus your application needs to be split into a linux part And into a trusted execution opti part The trusted execution part of these applications is called trusted application and it obviously has to run within opti on the linux side, however Opti provides a T client library which can be used to facilitate the communication between your Linux operating system application part and the trusted application part So you don't have to implement all the necessary communication yourself You just define the interfaces define the data you want to exchange and tell your application Which trusted application corresponds to it? Next up is an example of the TA Communication flow so the communication always starts within your client application on the left upper side of the black bar and your client application will then serialize its data and Hand off the data to the linux interface the linux interface on the other hand ensures that the data is ready to be sent off to the secure monitor and Sense of the data to the secure monitor subsequently the secure monitor then ensures that memory addresses are matching that necessary translation is drawn that Maybe the caches are flushed correctly before handing the data off to opti and Opti will finally decide which trusted application to hand the data to Depending on which application you want to communicate with the trusted application will then process the data as it sees fit i.e doing cryptographic operations or Calculating necessary checksums whatever the trusted application may do it will then Subsequently hand the data back to opti which will forward it to the secure monitor Which in turn hands it to the linux interface where the kernel driver will hand it finally back to your application and This is the normal communication flow how you communicate with your trusted application Next up are opti features One of the features opti is has is that you can use replay protected memory blocks Which are an emmc or nvme feature for rollback protected storage Repay protected memory blocks mean that and a One-time operation can be done with your emmc where you fuse a key into your emmc Which is used to authenticate the data which is sent to the emmc as this is a one-time operation And the key can never be changed afterwards Every week request sent to the emmc needs to be authenticated and Thus nobody can roll back the storage to a previous point because This person needs to have access to the authentication key But this is securely stored with an opti and cannot be accessed subsequently Opti also provides drivers for common DDR firewalls usually Applications or platforms provide a system a bit of their Random access memory to opti to the secure world But you subsequently have to ensure that the normal world cannot access the secure world memory because otherwise secrets would be leaked therefore, there are DDR access firewalls such as the trust zone address space controller 3a3 80 and 400 which are standard arm hardware controllers There's also an upstream kernel driver Maintained by the opti maintainers This means it's really easy to enable opti within your chosen platform. You just have to build opti and Load it however your platform requires it and then you enable the opti kernel driver and the opti client Interface which is called the t-subplicant, but I will talk about this later some more Platform support at the moment is available for iMix whether it is iMix 6 iMix 7 or iMix 8 processors There's some support for layerscape processors. There is support for STM32 MP1 The new application processor series from STM There's support for QEMO vExpress platforms, which is also used to test pull requests sent to the opti project There's support for high-key platforms support for the Raspberry Pi 3 because the Raspberry Pi is very accessible to Everyone however the Raspberry Pi 3 does not contain a DDR access firewall So it's not really fit for real-world applications Where you have the requirement that your secure world memory is protected and Then there's support for Rockchip and TI AM 335 for example Next up I'll talk about about opti persistent storage opti itself doesn't implement any driver to access for example emmc devices or SD cards opti uses a Demon running within linux for this which is called the t-subplicant the t-subplicant Receives the storage request from the Linux kernel via the Linux kernel interface and Subsequently stores data by either storing it on the Linux 5 system or the replay or sending it to the emmc for Storage within the replay protective memory blocks to ensure that Data stored on the Linux kernel cannot be read by the kernel or by the platform user opti encrypts and Authenticates this data using a unique key On your trusted application side the global platform API specifies a T persistent storage API, which you can use to store Persistent objects and retrieve them even after the platform was turned off The t-subplicant storage interface as there are no opti storage drivers as said before implements either access to the emmc by sending requests from opti off to the emmc Where the emmc will either store the data when it's authenticated correctly or it will reject the data request Or it can store it within the Linux files system However, you lose the replay protection obviously, which is provided by the emmc this way But this is really nice for development applications Next up are the use cases so one of the first use cases and Also, one of the ones I will be presenting is the trusted platform module use cases where you have PCR registers You can provide ceiling and attestation using this trusted application The next use case being pkcs11 Which can be used for signing or device authentication where you a where you are able to store a secret private key with on your device, which is able to verify that your device is really a Device which has been booted correctly as an example. There's also the trusted keys interface, which is currently Under discussion it provides ceiling for the Linux key rings within opti Other trusted use cases which could be implemented within opti are for example payment verification or On the other hand content decryption with the emm. However, you run into problems there because Eventually you can't simply decrypt the data within opti and hand it to the normal world because then the normal world can read The data so you have to ensure there's some kind of secure data path to get to the display engine Where it's encrypted until it's finally displayed on your device and As a last use case I came up with you could use opti for license management as an example Let's start with the pkcs11 example. I'll give you a short primer on pkcs11 Pkcs11 is a standard programming interface for hardware secure models such modules such as for example a UB key or a nitro key RSM This for example allows you to generate a private public key pair where your private data Your private key data is stored on your hardware secure module It's not stored on the computer where the private public key pair was generated on and the public key can be exported But the private key can never be exported from your hardware device You can send off data to your hardware device to sign But you can't export the private key from the device. It is securely bound to the device. It was generated on The pkcs11 API is also supported in a lot of a lot of Applications such as Chromium or SSH curl evolution Linux module signing for example can also use pkcs11 or the robust auto update controller or for generic code signing applications and usually implementation or Support is done within OpenSSL or GNU TLS OpenSSL has support for pkcs11 using the engine interface where you can use and OpenSSL pkcs11 engine to retrieve or So to tell OpenSSL that the private key does not reside on a local storage device It instead the resides on a hardware secure module and if you require Cryptographic operations from the private key you'll need to send off your requests via pkcs11 to the hardware secure module Let's look at the pkcs11 setup we I will be showing in the demo next I'm using the pkcs11 opti branch from Etienne Carrier He was the one who initially implemented the pkcs11 trusted application and We are also using the pkcs11 client branch from Etienne the client branch Implements the library where we bind against to talk to the pkcs11 trusted application Then we need to compile both with a configuration where we enable the trusted application Which is necessary and then we use the resulting libck.so as the pkcs11 module Since every pkcs11 library implements the same interface Utilities usually Allow you to load external libraries because they implement the specific interface And the current status of this trusted application is that it is being upstreamed into the main opti repository So eventually you won't need any of the external branches You will be able to download the upstream opti project enable the pkcs11 TA and everything will be working Which is not the case yet, but we are slowly getting there Let's take a look at the pkcs11 demo We have here a IMx6 device and I can show you that opti is currently running by outputting the DMS kernel log and grabbing for opti We can see that we are running opti revision 3.8 and the driver has been initialized successfully Next up we are going to export a pin which we are going to use when we initialize our opti pkcs11 trusted application and we're going to create an alias so we can access our trusted application without specifying the library's name every time you can see that the library name is libckclient.so And now we can list our available tokens within our trusted application we can see that we have Three slots available and all of these are uninitialized at the moment So next up what we are going to do is we're going to initialize a token and afterwards generate a private key on this device For this we need to specify that we want to init the token We want to init the initial pin to access the token set up the supervisor pin set up the new pin and specify the new pin on the command line interface We also specify that the new label of the token should be test and Then the token is successfully initialized and the user pin is also successfully initialized If we list the available slots again We can see now that the token label is set to test and the token manufacturer alinaro, which supervises the opti development and The token model being the opti trusted application and we can see all the token flags and firmware versions and serial numbers Those match up great Next up We are going to log in into the token and then are going to generate a new RSA 1024 bit key which doesn't take too long, but obviously bigger keys could be generated within the module With an ID of one and with a label of test key This takes a bit of time obviously and afterwards we have two new objects with an our pkcs 11 TA on the one hand We have the private key which is labeled with test key and we have a public key object with the slave Which is labeled with with test key This is fine since we just generated a public private key pair within our Hardware secure or our pkcs 11 trusted application next up We're going to list the available objects without log in this way We can see that only the public key object is accessible this way And if we lock in with the pin supplied beforehand, we can see that we can access the private key again So pkcs 11 TA always requires us to authenticate using the pin if we want to access data within the module which is restricted from access Next up. We're going to create a x509 certificate with a new RSA key to show how the open SSL pkcs 11 engine can be used The final test will be to start an open SSL Secure server to show that the secure server can access the private key within the hasm So we need to set up a path passphrase for the new key and then Answer some questions for the new x509 certificate as can be seen here. We're just going to name its test certificate, obviously and then we will now import the New key. We just generated for the certificate into our pkcs 11 TA Subsequently, we could delete the key from the file system for this We specify that we want to log into the token that we want to write a key Pam and it's going to be a private key It's going to have the ID of two and it's going to be labeled import key now we are asked for the private key passphrase again and Finally our object is imported correctly into our pkcs 11 TA Now if we log in again, we can see that we have two private key objects available the test key We produced beforehand and on the other hand We have the import key which we just imported onto the trusted application And now we're going to start the S server by specifying that we want to use the pkcs 11 engine The key form is going to be engine and then the key is not going to be on the local file system It's going to be a pkcs 11 URI where we say we want to access the test token with the ID of 02 and the certificate is stored on the local file system Then we have to enter the pkcs 11 token pin because we couldn't specify it on the command line and afterwards our S server starts successfully and This concludes our little demo of pkcs 11 Next up is the trusted platform module support I will start with a short primer on trusted platform modules So trusted platform modules are usually shortened to TPM and traditionally were a component on the board as seen on the right side image Which is a TPM module connected to a main board Usually those are connected via SPI or i2c, but nowadays we see more and more applications of using firmware TPMs For example for version TPM 2.0 where the TPM isn't running on a dedicated hardware chip It's instead running on a co-processor within our CPU or on the main board And one of the usage cases for TPM is that you are able to measure boot and Unlock trusted key material or data only if we have booted up correctly so you have your TPM connected to the to the processor and for example in the bootloader stage you would get the checksum of your Kernel image and feed it into the TPM to ensure that only if it's the correct kernel image will the TPM grant you access to Trusted key material on the TPM if another kernel image is booted the TPM won't give you access to the keys This is one of the specific Use cases for TPMs Let's talk a bit about the Microsoft firmware TPM setup I'm using in the demo We are using the upstream kernel driver, which is called T FTPM T the trusted application is from the MS Airsec FTPM GitHub repository and the setup is going to be that we are enabling the kernel driver building the FTPM with the opti development kit I will talk about afterwards and adding device tree nodes for The kernel two parts that we have a firmware TPM available and finally our TPM device should appear Let's get to the demo So we have our IMX6 board running as before and If I take a peek into the dev directory We can see that there is no TPM available at the moment and if I load the TPM kernel module We can see that we have now the two usual TPM devices available on our system and Subsequently, we can now use the TPM commands to for example get the capabilities of the TPM to firmware TPM available here or use it to get random data in this example just 20 bytes And we can see that the data is different every time. So the randomness should be working correctly now We are reading one of the PCR registers and we can see that it has not been used before it's all zeros So it has not been extended with a specific hash checksum What we are doing then is we're going to create a little test file with the contents of test Then we're going to calculate the char 256 sum over it and we're going to use this 200 char sum to extend our PCR by copying the sum we generated from the test file and If we now read back the PCR again We can see that it has changed, but it's not the sum of the char 256 sum we put in the PCRs are extended with a hash sum and in themselves hash again, so the contents of this Register can never be predicted unless you have the correct data and feed in the correct hashes in the correct order Yes, and this concludes our short demonstration of the TPM capabilities Let's get back to TA compilation When opti is compiled it produces a so-called devkit or development kit Which can be used to compile external trusted applications This was also used with the Microsoft firmware TPM since the firmware TPM Is not and will probably not be included within the opti project itself It will always be provided as an external trusted application What you do for this is you are going to compile opti which will output you the TA development kit and The TA development kit also contains the build system for your trusted application So you write your trusted application You have your trusted application sources and combine them with the TA dev kit and the build system and then can compile a trusted application For the opti version you are running on your system the opti interfaces should be fairly stable So even trusted applications compiled with other development kits should run on your opti Operate trusted execution environments Let's talk a bit about signing. So how does opti actually verify that your TA is allowed to be loaded Opti uses a public key compiled into opti for this and you are have to sign the TA with a private key Available on your device. Usually the private key is included within the TA development kit So you have to ensure that no malicious actor can access your development kit But that should be easy because it's a development material for your platform Opti then verifies these trusted application signatures on load and will refuse to load any application which is not signed correctly Furthermore opti provides two different storage locations You can either build your trusted application into opti and thus distributed with the opti binary Which is called the internal opti store Or you could store the binary within your linux file system Since the trusted application is signed Any modification of the trusted application will mean that it can't be loaded by opti any longer unless it is re-signed with the correct key This way even storage on the linux file system is possible However, sometimes you don't want anybody to be able to read the code of your application Even if it's available in binary form thus it may be more advisable to build your trusted application into opti If memory constraints permit this Let's talk a bit about how to secure opti So the required components to secure opti On a chosen platform apart from the platform independent stuff You have to do like replacing for example the trusted application signing key Is you require a hardware random number generator You will need some kind of facility to generate a unique key Which is only accessible from the secure world This is the unique key where all other key material is derived from To for example encrypt data for storage within linux Next up you will also need either a ddr or sram firewall to protect memory Which is used by the secure world from the normal world And often you also need some kind of device bus access policies in modern system on chip devices Often not only the cpu can read your memory or main memory data Also other devices such as the gpu or the ethernet interface can directly write to main memory and directly read from it So you want to ensure that these devices also can't access the secure world Furthermore, there is sock dependent integration which needs to be done Do you require a secure boot on your platform from the platform sock vendor? And what about bootloader integration? How is opti actually loaded on your platform? Let's start with securing opti on imx6 with a random number generator Many of the imx platforms provide a cryptographic accelerator and assurance module shortened to calm And the calm has an internal random number generator a internal hardware random number generator And now you have two choices what to do with this calm support within opti You can either use opti with runtime calm support where opti is able to access the calm at any time because it has a driver compiled in But this may lead to concurrency problems with the linux kernel And in this case your random numbers are just directly retrieved from the calm Every time opti requires new random data. It is retrieved from the calm The alternative is to use the calm to generate the initial seed for your pseudo random number generator a software random number generator with an opti In this case, you don't always require access to the calm only during the very early initialization where All of the time your linux is not running yet So you don't run into any concurrency problems where opti wants to access the calm And linux may want to access the calm at the same time, but linux isn't running in this case So you eliminate this concurrency problem And in this case you just provide the initial seed for your software pseudo random number generator to from the calm Next up is support for a hardware for a hardware unit key or the unit key where every other key material with an opti is derived from Again every imx6 processor and imx7 and imx8 as well Have a unique one-time programmable key which is fused into the fuses by nxp already at production of the device And luckily for us the calm can provide a hash over this key for verification This means that to verify that your one-time programmable key is different on every platform The calm is able to provide a hash over the key Which should be different on different devices coming from the factory So you can ensure that the one-time programmable key is unique for every device Luckily for us this hash is also different whether you are running it from the secure or normal world Since the calm is aware whether the processor requesting The hash over the key is in the normal or secure world. You will get a different hash Depending on whether you are in the normal or the secure world Thus we can use the secure world hash for our hardware unique key However, there's a kv a kvd here This is only possible if you enable higher assurance boot on the platform Otherwise Your calm key won't be unique and you need to enable higher assurance boot for this Down in the diagram you can see how the One-time programmable key is used by the calm to in the end With a hashing algorithm Provide the hardware unique key for our platform Next up let's talk about ddr firewalls IMX6 has a very standardized trust zone controller 380 And the driver for this was already available with an opti And I added support to derive the configuration for this trust zone address space controller from The configuration with an opti so opti needs to know where it's going to be loaded And how much ddr memory or main memory is available to it And we can use this static configuration To configure our ddr firewall in a way that the normal world will not be able to access The secure world And I also added support to lock the configuration The trust zone address space controller hardware block has a lock bit Which when set ensures that the configuration cannot be changed afterwards So we can ensure that no random memory accesses on the bus can modify our configuration And maybe destroy the security of our secure world memory Next up are the device bus policies on IMX6 The IMX6 has a central security unit For this the central security unit unit provides access policies for dma masters such as the gpu Ethernet or PCI if they are available on your platform and you can also specify which Which world is allowed to access a specific peripheral for example on certain smaller IMX6 processors There is not a calm available on the board. There's only a dcp A cryptographic co-processor available And you have to restrict access to this co-processor if linux is running Since the co-processor Has access to the one-time programmable key independent of which world is currently accessing the co-processor For this you can use the csu to Forbid any access from the normal world to the dcp and allow access only from the secure world And for access policies for dma masters This is currently done for the IMX6 ultralight platform, but others are very easy All you need to do is acquire the security reference manual and then look at the register layout to Disable access for any dma master which may want to access opti or secure world memory It's really easy. You just basically restrict access for every device except the cpu Next up is integration. You may want to enable or in case of IMX6 you need to enable support for high assurance boot for secure boot otherwise as said before the unique key won't be unique on your device and this is not something you want to happen Furthermore, you may want to verify your kernel via fit images And you may want to verify your root fs with the severity to ensure that nobody else has access to the software running on your platform Next up is bootloader integration. So when do you load opti on IMX6 processors? Do you load it before the kernel or do you load it during early startup of the bootloaders? of the bootloader Both have advantages and disadvantages if you load opti before the kernel You have a full bootloader running beforehand which may download opti from an external source Which is very nice for development. So you can deploy your opti binary Onto a network device and the bootloader will fetch opti from the network device and start it before the kernel But for in a production environment, you want to Have a really small code size Which is run before opti is started to ensure that no bugs creep in where anybody Could manipulate your bootloader to do something different before opti is started for you This you want to do very early startup of opti during the boot during the bootloader startup Both are supported within the barebox bootloader And then you need to do suck dependent integration The IMX6 leaves Opti loading to the bootloader as said before you can either load it early or you can load it right before the kernel But as an example for the stm32 mp1 There is support for the arm trusted firmware and only for the arm trusted firmware So opti loading is only supported through the arm trusted firmware on this platform At least in upstream arm trusted firmware versions i've looked into And the same is also true for many of the 64 bit platforms out there And which is also true for the IMX8 mq which also uses the arm trusted firmware So everything that's not 32 bits is very fixed on loading opti during startup of the arm trusted firmware Which is natural as far as I can say I'd like to offer my thanks to the opti maintainers, which are Jens Wieglander, Jerome Frosier And Etienne Caillet And they also provided a lot of review input and maintenance during my opti pull requests and during Getting the IMX6 platform ready for opti I'd especially like to thank Etienne again for the creation of the pkcs11 trusted application library And also Ricardo Saivetti for a lot of review and additional features He for example implemented loading of certificates into the pkcs11 trusted application I'd also like to thank nxp for a contribution of their upstream calm driver And they also currently do the maintenance of the IMX6 platform in upstream opti And last but not least, I'd like to thank our customers for funding the work on opti And believing that opti can be used to store Secrets on the device which can never be extracted from there So in conclusion, I'd like to say go out and use opti Tell me what your use cases look like And thank you very much