You can encrypt all or parts of a Power-Safe filesystem in order to protect its contents.
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.
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 set the crypto= option 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 set the crypto= option 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 | 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 a given domain to the path (a regular file or a directory). 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:
$ fsencrypt -vc check -p / ENCRYPTION_CHECK(Path:'/') FAILED: (18) - 'No support'
$ fsencrypt -vc enable -p / ENCRYPTION_CHECK(Path:'/') SUCCESS $ fsencrypt -vc check -p / ENCRYPTION_CHECK(Path:'/') NOTICE: Encryption is SUPPORTED)
$ fsencrypt -vcget -p /accounts/1000/secure/testfile GET_DOMAIN(Path:'/accounts/1000/secure/testfile') = 10 SUCCESS
$ fsencrypt -vc query -p/ -d11 QUERY_DOMAIN(Path:'/', Domain:11) NOTICE: Domain is UNUSED $ fsencrypt -vc query -p/ -d10 QUERY_DOMAIN(Path:'/', Domain:10) NOTICE: Domain is UNLOCKED