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.

To use file system encryption, choose one of the following approaches:

Secure storage service (automatic mode)

When you enable TrustFence in your project, Digi Embedded Yocto creates a systemd service called secure-storage-init that:

  • On the first run:

    • Creates a folder to hold encrypted data

    • Initializes the secure storage with a random encryption key

  • On subsequent runs:

    • Decrypts and mounts the folder so that it can be accessed by users/applications

This service allows you to deploy the firmware and let the device autonomously encrypt and decrypt your private data. Data is stored encrypted on the media, but it’s decrypted on boot, so that your applications can access it.

Configure the service

By default, Digi Embedded Yocto uses the path /mnt/data/private for encrypted data. The use of a separate partition than the rootfs on the default partition table is intentional. It allows you to isolate your secure data from the root file system partition, which is prone to be updated on system updates.

You can change this path to a custom one in on your project’s conf/local.conf, for instance:

conf/local.conf
TRUSTFENCE_FILE_BASED_ENCRYPT_DIR = "/mnt/data/my-secure-data"
It is important to note that fscrypt does not encrypt existing files in place. You must supply a path to an empty or non-existing directory for the systemd service to create and encrypt it.

If you configured a custom path, rebuild your project and deploy it in the device. For simplicity, this topic assumes you are using the default path.

Check the service

On the first boot, the service creates the folder and initializes the secure storage with a random key. You can check the status of the service with:

# systemctl status secure-storage-init
* secure-storage-init.service - Secure storage init (fscrypt)
     Loaded: loaded (/usr/lib/systemd/system/secure-storage-init.service; disabled; preset: disabled)
     Active: active (exited) since Thu 2025-05-29 20:59:13 UTC; 7s ago
    Process: 668 ExecStart=/usr/sbin/secure-storage-init.sh start (code=exited, status=0/SUCCESS)
   Main PID: 668 (code=exited, status=0/SUCCESS)
        CPU: 1.241s

May 29 20:59:12 ccmp13-dvk systemd[1]: Starting Secure storage init (fscrypt)...
May 29 20:59:12 ccmp13-dvk secure-storage-init.sh[668]: [secure-storage] create /mnt/data/private
May 29 20:59:12 ccmp13-dvk secure-storage-init.sh[668]: [secure-storage] verify if we are on EXT4
May 29 20:59:12 ccmp13-dvk secure-storage-init.sh[668]: [secure-storage] Check if mnt/data/tee exists
May 29 20:59:12 ccmp13-dvk secure-storage-init.sh[668]: [secure-storage] Generating master key directory at mnt/data/tee
May 29 20:59:12 ccmp13-dvk secure-storage-init.sh[668]: [secure-storage] check if we have already a key
May 29 20:59:13 ccmp13-dvk secure-storage-init.sh[668]: [secure-storage] Generating new random key
May 29 20:59:13 ccmp13-dvk secure-storage-init.sh[668]: [secure-storage] Secure storage ready at /mnt/data/private
May 29 20:59:13 ccmp13-dvk systemd[1]: Finished Secure storage init (fscrypt).

This shows if the service is running or if it has encountered any issue during initialization.

If the service is running normally, you can check that the directory has been created and is empty:

# ls /mnt/data/private
# 

You can now work normally, add files and directories inside this path and have your applications access it as a regular directory. 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.

Stop the service

You can stop the service at any time to end the secure session:

# systemctl stop secure-storage-init

This makes the plain data not visible anymore:

# 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.

You can manually start the service again. Otherwise, it will start automatically during the next boot.

Use manual commands (manual mode)

The following instructions show how to manually 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 a UBIFS partition on the NAND, you can skip this section. The UBIFS accepts encrypted files by default.

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 (only the first time), 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.

  • The systemd service (automatic mode) generates a random key. As a consequence, if the secure storage is removed/corrupted, the encrypted data cannot be recovered. Refer to the manual commands for using a known key.

For additional detail on fscrypt, refer to https://www.kernel.org/doc/html/v6.6/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"