Background

DM-Crypt is a disk encryption subsystem in the Linux kernel and can be used to protect sensitive data / intellectual property stored (IP) on external storage. For example, if an attacker copies the contents of the external storage media offline, they would not be able to decrypt the contents without the key used for encryption. On desktop systems, the encryption key is protected using user passwords. Standalone embedded Linux systems and IoT devices typically operate without any user interaction and thus need a hardware based mechanism for protecting the encryption key. This blog discusses leveraging the Linux kernel “trusted keys” feature using Trusted Execution Environment (TEE) backend to protect the dm-crypt encryption key.

 

“Trusted keys” overview

In short, trusted keys is a Linux kernel feature that supports loading/managing of keys secured by hardware into the Linux kernel keyring. Once loaded into the keyring, the keys can be used by other kernel sub-systems such as dm-crypt to encrypt disks. The key is only available at the kernel level and is not exposed to user space. At rest (device powered off), the key is sealed/encrypted by a hardware based mechanism and thus protected. As of Linux kernel 6.4, there are 3 supported backends for securing the key, based on the hardware root of trust source:

  • Trusted Platform Module (TPM)
  • Trusted Execution Environment (TEE)
  • NXP Cryptographic Acceleration and Assurance Module (CAAM)

In this blog, the Trusted Execution Environment backend is discussed; mainly because of its ease of use and for being relatively hardware platform agnostic.

 

Trusted keys with TEE backend

TEE provides a secure, hardware isolated environment for executing sensitive operations. In the context of Linux kernel ‘trusted keys’, the TEE OS (e.g.: OP-TEE) performs sealing (encrypt) and unsealing (de-crypt) of the trusted keys (e.g.: dm-crypt disk encryption keys). To perform the seal/unseal operation, the TEE uses a hardware unique key (HUK) supported by the underlying processor/SoC. The hardware unique key is typically burnt into the processor and is only accessible by TEE. Thus the trusted keys can be unsealed/decrypted only on that particular hardware. Apart from protecting the disk, this also has the added benefit of preventing cloning / counterfeiting of devices.

In order to use trusted keys with TEE backend::

  • Processor needs to support TEE (e.g.: ARM processors with TrustZone technology) and software support for TEE OS (e.g.: OP-TEE)
  • Support for Hardware Unique keys both from hardware and TEE OS driver standpoint (more on this in the next section)

Once the platform support is confirmed, in order to start using the trusted key mechanism, the high level steps are as follows:

  • First boot (one time setup):
    • Generate a trusted key, using the Linux keyctl user space command line tool
      • In case of TEE backend, the key is generated using hardware random number generator
    • Seal (encrypt) the key and save the sealed key blob on external storage (plain disk)
  • Subsequent boots:
    • Unseal the key blob and load it inside the kernel keyring (initiated from the keyctl utility)
    • Use the plain key inside the kernel keyring for disk encryption (e.g.: dm-crypt)

Simplified system overview of Linux kernel trusted keys with TEE backend

 

Hardware Unique key (HUK) support in OP-TEE

As discussed above, the underlying processor / SoC along with OP-TEE OS needs to support HUK. Below is a summary of the platforms that support HUK in OP-TEE OS as of version 3.21.0. Trusted keys can be seamlessly and consistently used on all of the below platforms.

 

Processor Family Hardware Unique Key (HUK) source in OP-TEE OS
STM32MP1 User programmed key in OTP fuse (OR)
Device ID encrypted using user programmed key in OTP fuse
Xilinx Zynq UltraScale+ Hash of Device DNA (FPGA/PL or PS eFuse) with optional User eFuses and then encrypted with the selected Device Key (PUF or User AES eFuse key)
Xilinx Versal Hash of Device DNA (eFuse) and then encrypted with the selected Device Key (PUF or User AES eFuse key)
NXP i.MX9 Obtained from EdgeLock Secure Enclave (API call)
NXP i.MX6/7/8 Obtained from CAAM Master Key Validation Blob based on NXP programmed unique OTP Master Key
NXP i.MX6ULL Derived from AES-CMAC operation using Data Co-Processor (DCP) with NXP programmed unique OTP key
TI AM62x/64x/65x “K3” DKEK (derived key encryption key) based on TI programmed OTP key and modifiers (context/label hardcoded in OP-TEE OS) via API call to System Controller
TI DRA7xx/AM57xx Passed in to OP-TEE via a secure memory stack by initial secure software
Marvell Armada OTP fuse

 

Getting started with dm-crypt using Linux “Trusted keys” with OP-TEE backend

While this example uses NXP’s i.MX93 EVK with a Linux distribution based on Yocto, the concepts and steps apply to all other processor families mentioned in the above section. Below are the steps to encrypt a disk using dm-crypt using a trusted key protected by the TEE backend:

1. Setup the host PC for building Yocto using the Yocto project manual or NXP’s user guide. Here we will be using NXP’s Yocto Langdale release (Linux 6.1.1_1.0.01) with imx93evk. On your host machine, setup Yocto:

$ mkdir imx
$ cd imx
$ repo init -u https://github.com/nxp-imx/imx-manifest -b imx-linux-langdale -m imx-6.1.1-1.0.1.xml
$ repo sync -j12
$ MACHINE=imx93evk DISTRO=fsl-imx-xwayland source ./imx-setup-release.sh -b bld-xwayland 

 

2. Enable CONFIG_TRUSTED_KEYS_TEE kernel config option via the kernel menuconfig and then save/exit.

$ bitbake -c menuconfig linux-imx

 

3. Build the target image.

$ bitbake imx-image-core

 

4. Flash the image onto the SD card.

$ sudo bmaptool copy tmp/deploy/images/imx93evk/imx-image-core-imx93evk.wic.zst /dev/sd<X>

 

5. Boot the board, login as “root” user. Generate a trusted key. In this case, a random 32 byte (256 bit) key is created in the kernel keyring (session). This key will be later used as the dm-crypt encryption key.

$ keyctl add trusted kmk "new 32" @s
683944763
$ keyctl show
Session Keyring
664115353 --alswrv      0     0  keyring: _ses
34693737 ----s-rv      0     0   \_ user: invocation_id
683944763 --alswrv      0     0   \_ trusted: kmk

 

6. The key generated in the previous step is not persistent and will be lost on reboot or logoff. Hence export and save the encrypted key blob to persistent storage. The key is encrypted by OP-TEE using a key derived from HUK and is exported as an encrypted blob to userspace and is then saved on the filesystem.

$ keyctl pipe 683944763  > kmk.blob

 

7. Now to create an encrypted filesystem, first create an empty file to hold the encrypted image.

$ dd if=/dev/zero of=encrypted.img bs=1M count=32 && sync
32+0 records in
32+0 records out
33554432 bytes (34 MB, 32 MiB) copied, 0.0995694 s, 337 MB/s

 

8. Load the file as a loopback device.

$ losetup /dev/loop0 encrypted.img
[ 1840.729859] loop0: detected capacity change from 0 to 65536

 

9. Use dmsetup to create an encrypted device on the loopback device using the trusted key. For more details on the command refer to https://gitlab.com/cryptsetup/cryptsetup/-/wikis/DMCrypt

$ dmsetup -v create encrypted --table "0 $(blockdev --getsz /dev/loop0) crypt aes-cbc-plain :32:trusted:kmk 0 /dev/loop0 0 1 sector_size:512"
Name:              encrypted
State:             ACTIVE
Read Ahead:        256
Tables present:    LIVE
Open count:        0
Event number:      0
Major, minor:      253, 0
Number of targets: 1

 

10. Create an ext4 filesystem on the encrypted block device

$ mkfs.ext4 /dev/mapper/encrypted
mke2fs 1.46.5 (30-Dec-2021)
Creating filesystem with 32768 1k blocks and 8192 inodes
Filesystem UUID: 30b0d11b-257e-4e59-b694-374c2e7a668a
Superblock backups stored on blocks:
        8193, 24577
Allocating group tables: done                            
Writing inode tables: done                            
Creating journal (4096 blocks): done
Writing superblocks and filesystem accounting information: done

 

11. Setup a mount point

$ mkdir /mnt/encrypted

 

12. Mount the mapped device

$ mount -t ext4 /dev/mapper/encrypted /mnt/encrypted/
[ 2175.884218] EXT4-fs (dm-0): mounted filesystem with ordered data mode. Quota mode: none.

 

13. Anything written to /mnt/encrypted is now encrypted on the fly and written back to the block device (/dev/loop0 in this case). Write an example file:

$ echo "This is a test of full disk encryption on i.MX" > /mnt/encrypted/readme.txt

 

14. Unmount the filesystem and reboot

$ sync && umount /mnt/encrypted/ && dmsetup remove encrypted && reboot
[ 2215.094990] EXT4-fs (dm-0): unmounting filesystem.

 

15. After the board re-boots, the key needs to be re-loaded to decrypt the dm-crypt volume. Import the encrypted blob to key retention service

$ keyctl add trusted kmk "load $(cat kmk.blob)" @s
1012097731

 

16. Load the loopback device

$ losetup /dev/loop0 encrypted.img
[  119.165176] loop0: detected capacity change from 0 to 65536

 

17. Use dmsetup with the previously used options to create the encrypted device mapping

$ dmsetup -v create encrypted --table "0 $(blockdev --getsz /dev/loop0) crypt aes-cbc-plain :32:trusted:kmk 0 /dev/loop0 0 1 sector_size:512"
Name:              encrypted
State:             ACTIVE
Read Ahead:        256
Tables present:    LIVE
Open count:        0
Event number:      0
Major, minor:      253, 0
Number of targets: 1

18. Mount the mapped device

$ mount /dev/mapper/encrypted /mnt/encrypted/
[  188.831105] EXT4-fs (dm-0): mounted filesystem with ordered data mode. Quota mode: none.

 

19. Verify contents of file (from step 13)

$ cat /mnt/encrypted/readme.txt
This is a test of full disk encryption on i.MX

 

Security Considerations

Now that we learnt how to protect data / IP using dm-crypt encryption using trusted keys, to fully secure the device there are other things that need to be done.

1) HUK Source Set Up

Many semiconductor vendors have added processor support for OP-TEE OS without actually implementing support for HUK. In this case OP-TEE defaults to a “hardcoded” HUK. Understanding the source of HUK is paramount to device security. Developers leveraging the TEE backend need to ensure the HUK source is properly set up.

 

2) Secure Boot and Chain of Trust Implementation

From a security standpoint the HUK and derived key needs to be kept secret. In order to do so, the device manufacturer needs to ensure only authenticated software runs on the device. Thus secure boot and chain of trust needs to be implemented i.e. all software running on the device needs to be signed and authenticated before execution. Otherwise an attacker can replace the device with custom firmware and obtain the HUK and thus decrypt the data / IP.

 

3) Consider Linux Kernel Hardening

Security relies on defense in depth i.e. a single failure in security does not lead to compromise of the entire system. For example, if the Linux kernel gets compromised due to a vulnerability, then the disk encryption key can be exposed since it resides in plain (unencrypted) inside kernel space. In order to reduce the attack surface, consider Linux kernel hardening as detailed in this blog.

Conclusion

Linux trusted keys with OP-TEE backend provides a consistent and platform/processor abstracted way of implementing disk encryption to protect your data / IP. With the growing trend of semiconductor vendors supporting OP-TEE OS with hardware based root of trust, it makes adoption of this security feature easier.

All of the above security functionality and more is implemented in our ready-to-use VigiShield Secure By Design offering.

 

References

The following are the references that were used to help create this piece:

 

Simplify Security with Timesys

At Timesys, our goal is to keep you ahead of the next security threat, help you design security into your devices and keep them secure while in the field—AND get your products to market faster with our PSA Certified VigiShield Secure By Design security feature implementation. 

Contact us today to begin your journey to a more simplified, secure product.

 

Akshay Bhat is CTO at Timesys. He oversees the strategic direction of Timesys’ technology roadmap. With more than 16 years of industry experience with embedded systems software development and security, Akshay’s focus is on Timesys solutions that transform the software development lifecycle for embedded and enable the development of embedded system products with stronger security. Akshay has authored numerous embedded Linux and industry articles and delivered several embedded systems security presentations. He received his MS in Electrical Engineering from NYU Polytechnic University.

About Timesys

Timesys has extensive experience with embedded system development and lifecycle management. Timesys has been instrumental in working with global leader semiconductor manufacturers with smart, quick and quality solutions for highly complex systems with accelerated product innovation and multiple product variants.