fscrypt is a kernel library that supports encryption of files and directories at the filesystem level rather than at the block device level. This allows it to encrypt different files with different keys and to support unencrypted files on the same file system.

TrustFence file system encryption functionality

Embedded devices often require file encryption on unattended devices. To access a directory, these unattended devices must be able to access the decryption key autonomously. That key must therefore be secured, but accessible.

Digi TrustFence offers this functionality by providing a modified version of the fscrypt library that makes use of OP-TEE secure storage implementation to save the keys in encrypted form.

Enable TrustFence in your project

Enable TrustFence in your project to have support for the file system encryption functionality:

conf/local.conf
INHERIT += "trustfence"

Build your project and deploy the images to your device.

Use file system encryption

Digi offers a trusted application, trustfence-fscrypt, which uses the fscrypt kernel API for file-level encryption. The trustfence-fscrypt application uses the OP-TEE secure storage feature to store the fscrypt master key on the file system. This application is the only one that can read the key from the secure storage to decrypt the files and folders on the file system.

The following instructions show how to create and encrypt a folder on your file system.

1. Prepare the file system to accept encrypted data

Support for encryption on the file system is enabled on the kernel through the configuration option CONFIG_FS_ENCRYPTION. This configuration option is enabled by default when TrustFence is enabled on your Digi Embedded Yocto project.

If you plan to store your encrypted data on an ext4 file system, the ext4 superblock must have the encryption support flag enabled. Check if the ext4 filesystem on your partition has the encrypted flag enabled:

# tune2fs -l <device> | grep features
Filesystem features: has_journal ext_attr resize_inode dir_index filetype extent 64bit flex_bg sparse_super large_file huge
_file dir_nlink extra_isize metadata_csum

where <device> is the block device that contains the ext4 file system where you want to store your encrypted data (such as /dev/mmcblk0p9).

This command shows the features enabled in the ext4 file system superblock. If the string encrypt is among the supported features, the partition is ready to be used. If it does not appear (like in the example above), enable the encryption support as follows:

# tune2fs -O encrypt <device>

Checking the ext4 superblock should now show the encrypt string among the supported features:

# tune2fs -l <device> | grep features
Filesystem features: has_journal ext_attr resize_inode dir_index filetype extent 64bit flex_bg encrypt sparse_super large_file huge
_file dir_nlink extra_isize metadata_csum

2. Create the folder to encrypt

It is important to note that fscrypt does not encrypt existing files in place. You must first create an empty directory to have it encrypted.

Create an empty folder where you will store your sensitive data, for instance:

# mkdir -p /mnt/data/private

3. Create a key and associate it with the directory

To start encryption on the empty directory, you must provide a key that will be stored encrypted on the secure storage.

This step must only be done once. When the key is saved on the secure storage, the application will use it to decrypt the data.

You have two options, each with pros and cons:

Manually provide a key

The trustfence-fscrypt tool has a --new-key option that accepts a base64-encoded key of 64 bytes.

  • Pros: When you know the key, you can save it on a secure database. This lets you recover encrypted folders in case the secure storage is deleted/corrupted.

  • Cons: You do need to provide the key, which may not be desired on automated manufacturing environments.

To manually provide a key, calculate the base64 encoding of the key. You want to perform this operation on a secure host computer where you will save the key for eventual recovery. For instance, create a 64-byte random key:

$ head -c 64 /dev/urandom | base64 -w 0 | xargs
SccKczktAqe5Cc2bz+yq80c7oebKTU5GPMVnc7YIcVLcoOwPBngwv/R5K15JrA8uUP0KsfBWGGmqHd6Gw4TDIw==
Consider saving the key on a secure database to have the possibility to recover encrypted data in case of accidental removal of the secure storage.

Associate the key with the empty folder using the base64 encoded value:

# trustfence-fscrypt --new-key=SccKczktAqe5Cc2bz+yq80c7oebKTU5GPMVnc7YIcVLcoOwPBngwv/R5K15JrA8uUP0KsfBWGGmqHd6Gw4TDIw== --start-session /mnt/data/private

Let the tool create a random key

The trustfence-fscrypt tool has a --new-key option that, when used without any parameter, automatically generates a random 64 byte key.

  • Pros: You don’t need to provide a key, which may be desirable in automated manufacturing environments.

  • Cons: You don’t have access to the key, so you won’t be able to recover data encrypted with the key in case the secure storage is deleted/corrupted. This, actually, might be a desired behavior if losing the data is preferred to the potential possibility of the key being leaked.

Start an encrypted session on the empty folder using an auto-generated key:

# trustfence-fscrypt --new-key --start-session /mnt/data/private

4. Store data on the folder

Once you have set up the folder with the encryption key, you can begin storing files.

As an example, create a subdirectory and a text file:

# mkdir /mnt/data/private/subdir1
# echo "Hello World" > /mnt/data/private/hello.txt
The data is stored encrypted on the media, but you’ll be able to see the contents of the files until you end the session.

5. End the session on the folder

End the session on the folder so that the plain data is not visible anymore:

# trustfence-fscrypt --end-session /mnt/data/private

List the contents of the folder:

# ls -l /mnt/data/private/
drwxr-xr-x    2 root     root           160 Jun 26 11:23 Fm9mEU_vBnyQyffH3iCZJPoN_LuGDwsXuyQQ9Jk_NbWyAtoO5DIKJg
-rw-r--r--    1 root     root            12 Jun 26 11:18 rERbENWXNFeFKMbez16UHRv_AoMuZNho5dsUXbeQnDVarnDo-Qt5yw

As you can see, only the filename and the file contents are encrypted. The metadata (type, size, permissions, dates…​) are not.

6. Start the session on the folder

To decrypt the contents, start the session on the folder:

# trustfence-fscrypt --start-session /mnt/data/private
You do not need to provide the key, which is obtained by the trusted application from the TEE secure storage.

Delete keys

Deleting a key from the secure storage implies you can no longer decrypt the data of the folder associated with the key, unless you manually generated the key and stored it on a secure computer (see Manually provide a key).

If you are intentionally deleting a key, it is recommended to also delete the folder associated with it and all its contents.

Delete a key from key storage for a specific path

When you no longer need the data in the encrypted folder, you can delete the key from the secure storage.

To delete a key associated with a folder:

# trustfence-fscrypt --del-key /mnt/data/private

Wipe all keys from the secure storage

The trustfence-fscrypt application has five slots to save five keys associated with folders. A wipe operation removes the keys from all five slots.

To wipe all keys from secure storage:

# trustfence-fscrypt --wipe-key-store

Notes and limitations

  • Only five keys (associated with five folders) are supported.

  • Without the key:

    • Directories may be listed, in which case the filenames will be listed in an encoded form derived from their ciphertext.

    • Files and directories may be deleted.

    • Regular files cannot be opened or truncated. Any regular file operations that require a file descriptor, such as read(), write(), mmap(), fallocate(), and ioctl(), are also forbidden.

For additional detail on fscrypt, refer to https://www.kernel.org/doc/html/v6.1/filesystems/fscrypt.html.

Disable file system encryption support

File system encryption support is enabled on the kernel, and the trustfence-fscrypt tool added simply by enabling TrustFence in your Digi Embedded Yocto project. If you don’t wish to have this functionality on your TrustFence-enabled images, set the following on your project’s conf/local.conf:

conf/local.conf
TRUSTFENCE_FILE_BASED_ENCRYPT = "0"