Encryption

You can encrypt all or parts of a Power-Safe filesystem in order to protect its contents.

Note: When you use an encrypted filesystem, read/write throughput rates and performance are lower and CPU usage is higher than when you use a nonencrypted filesystem.

You might need to encrypt different parts of the filesystem with different keys, and you might not need to encrypt some parts, so the Power-Safe filesystem lets you create multiple encryption domains, which you can lock or unlock as needed.

A domain can contain any number of files or directories, but a file or directory can belong to at most one domain. If you assign a domain to a directory, all files subsequently created in that directory are encrypted and inherit that domain. Assigning a domain to a directory doesn't introduce encryption to any files or directories that are already in it.

You can simply assign a domain to a directory or an empty file; the filesystem treats them in the same way because they don't have any content to encrypt. If you want to encrypt a file that isn't empty, you must make it migrate to a domain because the filesystem needs to decrypt the file, assign the new domain to it, and then encrypt the file again.

During operation, files that are assigned to a domain are encrypted, and the files' contents are available only when the associated domain is unlocked. When a domain is unlocked, all the files and directories under that domain—regardless of their locations in the volume—are unlocked as well, and are therefore accessible (as per basic file permissions). When a domain is locked, any access to file content belonging to that domain is denied.

Note: Locking and unlocking operations apply to an entire domain, not to specific files or directories.

Domain 0 (FS_CRYPTO_UNASSIGNED_DOMAIN) is always unlocked, and its contents are unencrypted; you can design your system to use any other domains. Valid domain numbers are 0–119.

In order to use encryption, you must first format the filesystem with the -E option for mkqnx6fs, and then specify crypto=enable for fs-qnx6.so. You can then use fsencrypt to manage the encryption. The chkqnx6fs utility automatically identifies the encryption format and verifies the integrity of the encryption data. It's also possible for you to use fsencrypt to enable encryption after you've formatted the volume and added content, but you must have specified crypto=enable when you started fs-qnx6.so.

Key types

Key type Description
File key Private and randomly generated at the time the file is created (if the file is assigned to a domain). Holds some information about the file to ensure integrity between a file and its key. Used to encrypt file data, and is encrypted by a domain key. Keys are managed by the filesystem and are hidden from the user.
Domain key Private and randomly generated at the time the domain is created. Used to encrypt all the file keys that belong to its domain, and is encrypted by a domain master key. Keys are managed by the filesystem and are hidden from the user.
Master key Optionally public, as it is supplied and managed by a third party (not the filesystem). Used to encrypt the domain key, required on domain creation and subsequent unlock requests.

Encryption types

The Power-Safe filesystem supports the following types of encryption:

Domain-encryption type Constant Description Key length
0 FS_CRYPTO_TYPE_NONE No encryption
1 FS_CRYPTO_TYPE_XTS AES-256, in XTS mode. The two keys are randomly generated. 512 bits
2 FS_CRYPTO_TYPE_CBC AES-256, in CBC mode (not currently implemented) 256 bits
3–99 Reserved for future use

Interface usage

To manage encryption from the command line, use fsencrypt; its -c option lets you specify the command to run. From your code, use the fscrypto library. You need to include both the <fs_crypto_api.h> and <sys/fs_crypto.h> header files. Many of the APIs return EOK on success and have a reply argument that provides more information.

API fsencrypt command Description
fs_crypto_check() check Determine if the underlying filesystem supports encryption
fs_crypto_domain_add() create Create the given domain/type if it doesn't already exist. You need to provide a 64-bit encryption key. From a program, you can create a locked or unlocked domain; fsencrypt always creates an unlocked domain.
fs_crypto_domain_key_change() change-key Change the master domain key used to encrypt the domain key
fs_crypto_domain_key_check() check-key Determine if a given domain key is valid
fs_crypto_domain_key_size() Return the size of keys needed for filesystem encryption
fs_crypto_domain_lock() lock Lock a domain, preventing access to the original contents of any file belonging to the given domain
fs_crypto_domain_query() query, query-all Get status information for a domain
fs_crypto_domain_remove() destroy Destroy a domain. You must be in the group that owns the filesystem's mountpoint. It isn't possible to retrieve any files in the domain after it's been destroyed.
fs_crypto_domain_unlock() unlock Unlock a domain, given the appropriate key data
fs_crypto_enable(), fs_crypto_enable_option() enable Enable encryption support on a volume that wasn't set up for it at formatting time
fs_crypto_file_get_domain() get Return the domain of a file or directory, if assigned
fs_crypto_file_set_domain() set Assign the path (a regular file or a directory) to a given domain. Regular files must have a length of zero. The domain replaces any domain previously assigned to the path.
fs_crypto_key_gen() -K or -k option Generate an encryption key from a password
fs_crypto_set_logging() -l and -v options Set the logging destination and verbosity

The library also includes some functions that you can use to move existing files and directories into an encryption domain. To do this, you unlock the source and destination domains, tag the files and directories that you want to move, and then start the migration, which the filesystem does in the background. These functions include:

API fsencrypt command Description
fs_crypto_migrate_control() migrate-start, migrate-stop, migrate-delay, migrate-units Control encryption migration within the filesystem
fs_crypto_migrate_path() migrate-path Mark an entire directory for migration into an encryption domain
fs_crypto_migrate_status() migrate-status Get the status of migration in the filesystem
fs_crypto_migrate_tag() migrate-tag, tag Mark a file for migration into an encryption domain

Examples

Here are some examples of the way you can use fsencrypt to manage filesystem encryption: