Encryption
You can encrypt all or parts of a Power-Safe filesystem in order to protect its contents.
- To use filesystem encryption, download the Encrypted Filesystem package from the QNX Software Center.
- 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.
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.
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_add_flags() | create | Create the given domain/type if it doesn't already exist, with the given locked state and flags for new file and domain keys. You need to provide a 64-bit encryption key. |
fs_crypto_domain_hard_lock() | lock | Lock a domain, preventing access to the original contents of any file belonging to it. With this function, the lock behavior is controlled by the FS_CRYPTO_HARD_LOCK_ACTION_ENFORCE flag. If this flag is not set, access is limited to clients that appear on a whitelist. If this flag is set, no clients have access. |
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 it. You must be in the group that owns the filesystem's mountpoint to lock a 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_domain_whitelist_configure() | — | Perform whitelist configuration for a domain whitelist |
fs_crypto_domain_whitelist_ctrl() | — | Perform a control action for a domain whitelist |
fs_crypto_domain_whitelist_ctrl_access_grant() | — | Grant a client access to a domain |
fs_crypto_domain_whitelist_ctrl_access_revoke() | — | Revoke a client's access to a domain |
fs_crypto_domain_whitelist_get_flags() | — | Get the flags for a domain whitelist |
fs_crypto_domain_whitelist_set_flags() | — | Set the flags for a domain whitelist. Whitelists are effective only when you're using a hard lock and you've not set the FS_CRYPTO_HARD_LOCK_ACTION_ENFORCE flag; for more details, see fs_crypto_domain_hard_lock() above. |
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 commands | 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:
- Determine if encryption is supported or enabled:
$ fsencrypt -vc check -p / ENCRYPTION_CHECK(Path:'/') FAILED: (18) - 'No support'
- Enable encryption on an existing filesystem:
$ fsencrypt -vc enable -p / ENCRYPTION_CHECK(Path:'/') SUCCESS $ fsencrypt -vc check -p / ENCRYPTION_CHECK(Path:'/') NOTICE: Encryption is SUPPORTED)
Note:This change is irreversible and forces two consecutive disk transactions to rewrite some data in the superblocks. - Determine if a file is encrypted. Files with the domain number of 0 aren't encrypted. A nonzero value means the file is assigned to a domain. Access to the file's original contents is determined by the status of the domain. The example below shows that the named file is assigned to domain 10:
$ fsencrypt -vcget -p /accounts/1000/secure/testfile GET_DOMAIN(Path:'/accounts/1000/secure/testfile') = 10 SUCCESS
- Determine if a domain is locked. If a domain is locked, reading the files within that domain yields encrypted data; unlocked domains yield the original file contents.
Unused
domains are ones that haven't yet been created. In the example below, domain 11 hasn't yet been created, and domain 10 is currently unlocked:$ 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