162306a36Sopenharmony_ci===================================== 262306a36Sopenharmony_ciFilesystem-level encryption (fscrypt) 362306a36Sopenharmony_ci===================================== 462306a36Sopenharmony_ci 562306a36Sopenharmony_ciIntroduction 662306a36Sopenharmony_ci============ 762306a36Sopenharmony_ci 862306a36Sopenharmony_cifscrypt is a library which filesystems can hook into to support 962306a36Sopenharmony_citransparent encryption of files and directories. 1062306a36Sopenharmony_ci 1162306a36Sopenharmony_ciNote: "fscrypt" in this document refers to the kernel-level portion, 1262306a36Sopenharmony_ciimplemented in ``fs/crypto/``, as opposed to the userspace tool 1362306a36Sopenharmony_ci`fscrypt <https://github.com/google/fscrypt>`_. This document only 1462306a36Sopenharmony_cicovers the kernel-level portion. For command-line examples of how to 1562306a36Sopenharmony_ciuse encryption, see the documentation for the userspace tool `fscrypt 1662306a36Sopenharmony_ci<https://github.com/google/fscrypt>`_. Also, it is recommended to use 1762306a36Sopenharmony_cithe fscrypt userspace tool, or other existing userspace tools such as 1862306a36Sopenharmony_ci`fscryptctl <https://github.com/google/fscryptctl>`_ or `Android's key 1962306a36Sopenharmony_cimanagement system 2062306a36Sopenharmony_ci<https://source.android.com/security/encryption/file-based>`_, over 2162306a36Sopenharmony_ciusing the kernel's API directly. Using existing tools reduces the 2262306a36Sopenharmony_cichance of introducing your own security bugs. (Nevertheless, for 2362306a36Sopenharmony_cicompleteness this documentation covers the kernel's API anyway.) 2462306a36Sopenharmony_ci 2562306a36Sopenharmony_ciUnlike dm-crypt, fscrypt operates at the filesystem level rather than 2662306a36Sopenharmony_ciat the block device level. This allows it to encrypt different files 2762306a36Sopenharmony_ciwith different keys and to have unencrypted files on the same 2862306a36Sopenharmony_cifilesystem. This is useful for multi-user systems where each user's 2962306a36Sopenharmony_cidata-at-rest needs to be cryptographically isolated from the others. 3062306a36Sopenharmony_ciHowever, except for filenames, fscrypt does not encrypt filesystem 3162306a36Sopenharmony_cimetadata. 3262306a36Sopenharmony_ci 3362306a36Sopenharmony_ciUnlike eCryptfs, which is a stacked filesystem, fscrypt is integrated 3462306a36Sopenharmony_cidirectly into supported filesystems --- currently ext4, F2FS, and 3562306a36Sopenharmony_ciUBIFS. This allows encrypted files to be read and written without 3662306a36Sopenharmony_cicaching both the decrypted and encrypted pages in the pagecache, 3762306a36Sopenharmony_cithereby nearly halving the memory used and bringing it in line with 3862306a36Sopenharmony_ciunencrypted files. Similarly, half as many dentries and inodes are 3962306a36Sopenharmony_cineeded. eCryptfs also limits encrypted filenames to 143 bytes, 4062306a36Sopenharmony_cicausing application compatibility issues; fscrypt allows the full 255 4162306a36Sopenharmony_cibytes (NAME_MAX). Finally, unlike eCryptfs, the fscrypt API can be 4262306a36Sopenharmony_ciused by unprivileged users, with no need to mount anything. 4362306a36Sopenharmony_ci 4462306a36Sopenharmony_cifscrypt does not support encrypting files in-place. Instead, it 4562306a36Sopenharmony_cisupports marking an empty directory as encrypted. Then, after 4662306a36Sopenharmony_ciuserspace provides the key, all regular files, directories, and 4762306a36Sopenharmony_cisymbolic links created in that directory tree are transparently 4862306a36Sopenharmony_ciencrypted. 4962306a36Sopenharmony_ci 5062306a36Sopenharmony_ciThreat model 5162306a36Sopenharmony_ci============ 5262306a36Sopenharmony_ci 5362306a36Sopenharmony_ciOffline attacks 5462306a36Sopenharmony_ci--------------- 5562306a36Sopenharmony_ci 5662306a36Sopenharmony_ciProvided that userspace chooses a strong encryption key, fscrypt 5762306a36Sopenharmony_ciprotects the confidentiality of file contents and filenames in the 5862306a36Sopenharmony_cievent of a single point-in-time permanent offline compromise of the 5962306a36Sopenharmony_ciblock device content. fscrypt does not protect the confidentiality of 6062306a36Sopenharmony_cinon-filename metadata, e.g. file sizes, file permissions, file 6162306a36Sopenharmony_citimestamps, and extended attributes. Also, the existence and location 6262306a36Sopenharmony_ciof holes (unallocated blocks which logically contain all zeroes) in 6362306a36Sopenharmony_cifiles is not protected. 6462306a36Sopenharmony_ci 6562306a36Sopenharmony_cifscrypt is not guaranteed to protect confidentiality or authenticity 6662306a36Sopenharmony_ciif an attacker is able to manipulate the filesystem offline prior to 6762306a36Sopenharmony_cian authorized user later accessing the filesystem. 6862306a36Sopenharmony_ci 6962306a36Sopenharmony_ciOnline attacks 7062306a36Sopenharmony_ci-------------- 7162306a36Sopenharmony_ci 7262306a36Sopenharmony_cifscrypt (and storage encryption in general) can only provide limited 7362306a36Sopenharmony_ciprotection, if any at all, against online attacks. In detail: 7462306a36Sopenharmony_ci 7562306a36Sopenharmony_ciSide-channel attacks 7662306a36Sopenharmony_ci~~~~~~~~~~~~~~~~~~~~ 7762306a36Sopenharmony_ci 7862306a36Sopenharmony_cifscrypt is only resistant to side-channel attacks, such as timing or 7962306a36Sopenharmony_cielectromagnetic attacks, to the extent that the underlying Linux 8062306a36Sopenharmony_ciCryptographic API algorithms or inline encryption hardware are. If a 8162306a36Sopenharmony_civulnerable algorithm is used, such as a table-based implementation of 8262306a36Sopenharmony_ciAES, it may be possible for an attacker to mount a side channel attack 8362306a36Sopenharmony_ciagainst the online system. Side channel attacks may also be mounted 8462306a36Sopenharmony_ciagainst applications consuming decrypted data. 8562306a36Sopenharmony_ci 8662306a36Sopenharmony_ciUnauthorized file access 8762306a36Sopenharmony_ci~~~~~~~~~~~~~~~~~~~~~~~~ 8862306a36Sopenharmony_ci 8962306a36Sopenharmony_ciAfter an encryption key has been added, fscrypt does not hide the 9062306a36Sopenharmony_ciplaintext file contents or filenames from other users on the same 9162306a36Sopenharmony_cisystem. Instead, existing access control mechanisms such as file mode 9262306a36Sopenharmony_cibits, POSIX ACLs, LSMs, or namespaces should be used for this purpose. 9362306a36Sopenharmony_ci 9462306a36Sopenharmony_ci(For the reasoning behind this, understand that while the key is 9562306a36Sopenharmony_ciadded, the confidentiality of the data, from the perspective of the 9662306a36Sopenharmony_cisystem itself, is *not* protected by the mathematical properties of 9762306a36Sopenharmony_ciencryption but rather only by the correctness of the kernel. 9862306a36Sopenharmony_ciTherefore, any encryption-specific access control checks would merely 9962306a36Sopenharmony_cibe enforced by kernel *code* and therefore would be largely redundant 10062306a36Sopenharmony_ciwith the wide variety of access control mechanisms already available.) 10162306a36Sopenharmony_ci 10262306a36Sopenharmony_ciKernel memory compromise 10362306a36Sopenharmony_ci~~~~~~~~~~~~~~~~~~~~~~~~ 10462306a36Sopenharmony_ci 10562306a36Sopenharmony_ciAn attacker who compromises the system enough to read from arbitrary 10662306a36Sopenharmony_cimemory, e.g. by mounting a physical attack or by exploiting a kernel 10762306a36Sopenharmony_cisecurity vulnerability, can compromise all encryption keys that are 10862306a36Sopenharmony_cicurrently in use. 10962306a36Sopenharmony_ci 11062306a36Sopenharmony_ciHowever, fscrypt allows encryption keys to be removed from the kernel, 11162306a36Sopenharmony_ciwhich may protect them from later compromise. 11262306a36Sopenharmony_ci 11362306a36Sopenharmony_ciIn more detail, the FS_IOC_REMOVE_ENCRYPTION_KEY ioctl (or the 11462306a36Sopenharmony_ciFS_IOC_REMOVE_ENCRYPTION_KEY_ALL_USERS ioctl) can wipe a master 11562306a36Sopenharmony_ciencryption key from kernel memory. If it does so, it will also try to 11662306a36Sopenharmony_cievict all cached inodes which had been "unlocked" using the key, 11762306a36Sopenharmony_cithereby wiping their per-file keys and making them once again appear 11862306a36Sopenharmony_ci"locked", i.e. in ciphertext or encrypted form. 11962306a36Sopenharmony_ci 12062306a36Sopenharmony_ciHowever, these ioctls have some limitations: 12162306a36Sopenharmony_ci 12262306a36Sopenharmony_ci- Per-file keys for in-use files will *not* be removed or wiped. 12362306a36Sopenharmony_ci Therefore, for maximum effect, userspace should close the relevant 12462306a36Sopenharmony_ci encrypted files and directories before removing a master key, as 12562306a36Sopenharmony_ci well as kill any processes whose working directory is in an affected 12662306a36Sopenharmony_ci encrypted directory. 12762306a36Sopenharmony_ci 12862306a36Sopenharmony_ci- The kernel cannot magically wipe copies of the master key(s) that 12962306a36Sopenharmony_ci userspace might have as well. Therefore, userspace must wipe all 13062306a36Sopenharmony_ci copies of the master key(s) it makes as well; normally this should 13162306a36Sopenharmony_ci be done immediately after FS_IOC_ADD_ENCRYPTION_KEY, without waiting 13262306a36Sopenharmony_ci for FS_IOC_REMOVE_ENCRYPTION_KEY. Naturally, the same also applies 13362306a36Sopenharmony_ci to all higher levels in the key hierarchy. Userspace should also 13462306a36Sopenharmony_ci follow other security precautions such as mlock()ing memory 13562306a36Sopenharmony_ci containing keys to prevent it from being swapped out. 13662306a36Sopenharmony_ci 13762306a36Sopenharmony_ci- In general, decrypted contents and filenames in the kernel VFS 13862306a36Sopenharmony_ci caches are freed but not wiped. Therefore, portions thereof may be 13962306a36Sopenharmony_ci recoverable from freed memory, even after the corresponding key(s) 14062306a36Sopenharmony_ci were wiped. To partially solve this, you can set 14162306a36Sopenharmony_ci CONFIG_PAGE_POISONING=y in your kernel config and add page_poison=1 14262306a36Sopenharmony_ci to your kernel command line. However, this has a performance cost. 14362306a36Sopenharmony_ci 14462306a36Sopenharmony_ci- Secret keys might still exist in CPU registers, in crypto 14562306a36Sopenharmony_ci accelerator hardware (if used by the crypto API to implement any of 14662306a36Sopenharmony_ci the algorithms), or in other places not explicitly considered here. 14762306a36Sopenharmony_ci 14862306a36Sopenharmony_ciLimitations of v1 policies 14962306a36Sopenharmony_ci~~~~~~~~~~~~~~~~~~~~~~~~~~ 15062306a36Sopenharmony_ci 15162306a36Sopenharmony_civ1 encryption policies have some weaknesses with respect to online 15262306a36Sopenharmony_ciattacks: 15362306a36Sopenharmony_ci 15462306a36Sopenharmony_ci- There is no verification that the provided master key is correct. 15562306a36Sopenharmony_ci Therefore, a malicious user can temporarily associate the wrong key 15662306a36Sopenharmony_ci with another user's encrypted files to which they have read-only 15762306a36Sopenharmony_ci access. Because of filesystem caching, the wrong key will then be 15862306a36Sopenharmony_ci used by the other user's accesses to those files, even if the other 15962306a36Sopenharmony_ci user has the correct key in their own keyring. This violates the 16062306a36Sopenharmony_ci meaning of "read-only access". 16162306a36Sopenharmony_ci 16262306a36Sopenharmony_ci- A compromise of a per-file key also compromises the master key from 16362306a36Sopenharmony_ci which it was derived. 16462306a36Sopenharmony_ci 16562306a36Sopenharmony_ci- Non-root users cannot securely remove encryption keys. 16662306a36Sopenharmony_ci 16762306a36Sopenharmony_ciAll the above problems are fixed with v2 encryption policies. For 16862306a36Sopenharmony_cithis reason among others, it is recommended to use v2 encryption 16962306a36Sopenharmony_cipolicies on all new encrypted directories. 17062306a36Sopenharmony_ci 17162306a36Sopenharmony_ciKey hierarchy 17262306a36Sopenharmony_ci============= 17362306a36Sopenharmony_ci 17462306a36Sopenharmony_ciMaster Keys 17562306a36Sopenharmony_ci----------- 17662306a36Sopenharmony_ci 17762306a36Sopenharmony_ciEach encrypted directory tree is protected by a *master key*. Master 17862306a36Sopenharmony_cikeys can be up to 64 bytes long, and must be at least as long as the 17962306a36Sopenharmony_cigreater of the security strength of the contents and filenames 18062306a36Sopenharmony_ciencryption modes being used. For example, if any AES-256 mode is 18162306a36Sopenharmony_ciused, the master key must be at least 256 bits, i.e. 32 bytes. A 18262306a36Sopenharmony_cistricter requirement applies if the key is used by a v1 encryption 18362306a36Sopenharmony_cipolicy and AES-256-XTS is used; such keys must be 64 bytes. 18462306a36Sopenharmony_ci 18562306a36Sopenharmony_ciTo "unlock" an encrypted directory tree, userspace must provide the 18662306a36Sopenharmony_ciappropriate master key. There can be any number of master keys, each 18762306a36Sopenharmony_ciof which protects any number of directory trees on any number of 18862306a36Sopenharmony_cifilesystems. 18962306a36Sopenharmony_ci 19062306a36Sopenharmony_ciMaster keys must be real cryptographic keys, i.e. indistinguishable 19162306a36Sopenharmony_cifrom random bytestrings of the same length. This implies that users 19262306a36Sopenharmony_ci**must not** directly use a password as a master key, zero-pad a 19362306a36Sopenharmony_cishorter key, or repeat a shorter key. Security cannot be guaranteed 19462306a36Sopenharmony_ciif userspace makes any such error, as the cryptographic proofs and 19562306a36Sopenharmony_cianalysis would no longer apply. 19662306a36Sopenharmony_ci 19762306a36Sopenharmony_ciInstead, users should generate master keys either using a 19862306a36Sopenharmony_cicryptographically secure random number generator, or by using a KDF 19962306a36Sopenharmony_ci(Key Derivation Function). The kernel does not do any key stretching; 20062306a36Sopenharmony_citherefore, if userspace derives the key from a low-entropy secret such 20162306a36Sopenharmony_cias a passphrase, it is critical that a KDF designed for this purpose 20262306a36Sopenharmony_cibe used, such as scrypt, PBKDF2, or Argon2. 20362306a36Sopenharmony_ci 20462306a36Sopenharmony_ciKey derivation function 20562306a36Sopenharmony_ci----------------------- 20662306a36Sopenharmony_ci 20762306a36Sopenharmony_ciWith one exception, fscrypt never uses the master key(s) for 20862306a36Sopenharmony_ciencryption directly. Instead, they are only used as input to a KDF 20962306a36Sopenharmony_ci(Key Derivation Function) to derive the actual keys. 21062306a36Sopenharmony_ci 21162306a36Sopenharmony_ciThe KDF used for a particular master key differs depending on whether 21262306a36Sopenharmony_cithe key is used for v1 encryption policies or for v2 encryption 21362306a36Sopenharmony_cipolicies. Users **must not** use the same key for both v1 and v2 21462306a36Sopenharmony_ciencryption policies. (No real-world attack is currently known on this 21562306a36Sopenharmony_cispecific case of key reuse, but its security cannot be guaranteed 21662306a36Sopenharmony_cisince the cryptographic proofs and analysis would no longer apply.) 21762306a36Sopenharmony_ci 21862306a36Sopenharmony_ciFor v1 encryption policies, the KDF only supports deriving per-file 21962306a36Sopenharmony_ciencryption keys. It works by encrypting the master key with 22062306a36Sopenharmony_ciAES-128-ECB, using the file's 16-byte nonce as the AES key. The 22162306a36Sopenharmony_ciresulting ciphertext is used as the derived key. If the ciphertext is 22262306a36Sopenharmony_cilonger than needed, then it is truncated to the needed length. 22362306a36Sopenharmony_ci 22462306a36Sopenharmony_ciFor v2 encryption policies, the KDF is HKDF-SHA512. The master key is 22562306a36Sopenharmony_cipassed as the "input keying material", no salt is used, and a distinct 22662306a36Sopenharmony_ci"application-specific information string" is used for each distinct 22762306a36Sopenharmony_cikey to be derived. For example, when a per-file encryption key is 22862306a36Sopenharmony_ciderived, the application-specific information string is the file's 22962306a36Sopenharmony_cinonce prefixed with "fscrypt\\0" and a context byte. Different 23062306a36Sopenharmony_cicontext bytes are used for other types of derived keys. 23162306a36Sopenharmony_ci 23262306a36Sopenharmony_ciHKDF-SHA512 is preferred to the original AES-128-ECB based KDF because 23362306a36Sopenharmony_ciHKDF is more flexible, is nonreversible, and evenly distributes 23462306a36Sopenharmony_cientropy from the master key. HKDF is also standardized and widely 23562306a36Sopenharmony_ciused by other software, whereas the AES-128-ECB based KDF is ad-hoc. 23662306a36Sopenharmony_ci 23762306a36Sopenharmony_ciPer-file encryption keys 23862306a36Sopenharmony_ci------------------------ 23962306a36Sopenharmony_ci 24062306a36Sopenharmony_ciSince each master key can protect many files, it is necessary to 24162306a36Sopenharmony_ci"tweak" the encryption of each file so that the same plaintext in two 24262306a36Sopenharmony_cifiles doesn't map to the same ciphertext, or vice versa. In most 24362306a36Sopenharmony_cicases, fscrypt does this by deriving per-file keys. When a new 24462306a36Sopenharmony_ciencrypted inode (regular file, directory, or symlink) is created, 24562306a36Sopenharmony_cifscrypt randomly generates a 16-byte nonce and stores it in the 24662306a36Sopenharmony_ciinode's encryption xattr. Then, it uses a KDF (as described in `Key 24762306a36Sopenharmony_ciderivation function`_) to derive the file's key from the master key 24862306a36Sopenharmony_ciand nonce. 24962306a36Sopenharmony_ci 25062306a36Sopenharmony_ciKey derivation was chosen over key wrapping because wrapped keys would 25162306a36Sopenharmony_cirequire larger xattrs which would be less likely to fit in-line in the 25262306a36Sopenharmony_cifilesystem's inode table, and there didn't appear to be any 25362306a36Sopenharmony_cisignificant advantages to key wrapping. In particular, currently 25462306a36Sopenharmony_cithere is no requirement to support unlocking a file with multiple 25562306a36Sopenharmony_cialternative master keys or to support rotating master keys. Instead, 25662306a36Sopenharmony_cithe master keys may be wrapped in userspace, e.g. as is done by the 25762306a36Sopenharmony_ci`fscrypt <https://github.com/google/fscrypt>`_ tool. 25862306a36Sopenharmony_ci 25962306a36Sopenharmony_ciDIRECT_KEY policies 26062306a36Sopenharmony_ci------------------- 26162306a36Sopenharmony_ci 26262306a36Sopenharmony_ciThe Adiantum encryption mode (see `Encryption modes and usage`_) is 26362306a36Sopenharmony_cisuitable for both contents and filenames encryption, and it accepts 26462306a36Sopenharmony_cilong IVs --- long enough to hold both an 8-byte logical block number 26562306a36Sopenharmony_ciand a 16-byte per-file nonce. Also, the overhead of each Adiantum key 26662306a36Sopenharmony_ciis greater than that of an AES-256-XTS key. 26762306a36Sopenharmony_ci 26862306a36Sopenharmony_ciTherefore, to improve performance and save memory, for Adiantum a 26962306a36Sopenharmony_ci"direct key" configuration is supported. When the user has enabled 27062306a36Sopenharmony_cithis by setting FSCRYPT_POLICY_FLAG_DIRECT_KEY in the fscrypt policy, 27162306a36Sopenharmony_ciper-file encryption keys are not used. Instead, whenever any data 27262306a36Sopenharmony_ci(contents or filenames) is encrypted, the file's 16-byte nonce is 27362306a36Sopenharmony_ciincluded in the IV. Moreover: 27462306a36Sopenharmony_ci 27562306a36Sopenharmony_ci- For v1 encryption policies, the encryption is done directly with the 27662306a36Sopenharmony_ci master key. Because of this, users **must not** use the same master 27762306a36Sopenharmony_ci key for any other purpose, even for other v1 policies. 27862306a36Sopenharmony_ci 27962306a36Sopenharmony_ci- For v2 encryption policies, the encryption is done with a per-mode 28062306a36Sopenharmony_ci key derived using the KDF. Users may use the same master key for 28162306a36Sopenharmony_ci other v2 encryption policies. 28262306a36Sopenharmony_ci 28362306a36Sopenharmony_ciIV_INO_LBLK_64 policies 28462306a36Sopenharmony_ci----------------------- 28562306a36Sopenharmony_ci 28662306a36Sopenharmony_ciWhen FSCRYPT_POLICY_FLAG_IV_INO_LBLK_64 is set in the fscrypt policy, 28762306a36Sopenharmony_cithe encryption keys are derived from the master key, encryption mode 28862306a36Sopenharmony_cinumber, and filesystem UUID. This normally results in all files 28962306a36Sopenharmony_ciprotected by the same master key sharing a single contents encryption 29062306a36Sopenharmony_cikey and a single filenames encryption key. To still encrypt different 29162306a36Sopenharmony_cifiles' data differently, inode numbers are included in the IVs. 29262306a36Sopenharmony_ciConsequently, shrinking the filesystem may not be allowed. 29362306a36Sopenharmony_ci 29462306a36Sopenharmony_ciThis format is optimized for use with inline encryption hardware 29562306a36Sopenharmony_cicompliant with the UFS standard, which supports only 64 IV bits per 29662306a36Sopenharmony_ciI/O request and may have only a small number of keyslots. 29762306a36Sopenharmony_ci 29862306a36Sopenharmony_ciIV_INO_LBLK_32 policies 29962306a36Sopenharmony_ci----------------------- 30062306a36Sopenharmony_ci 30162306a36Sopenharmony_ciIV_INO_LBLK_32 policies work like IV_INO_LBLK_64, except that for 30262306a36Sopenharmony_ciIV_INO_LBLK_32, the inode number is hashed with SipHash-2-4 (where the 30362306a36Sopenharmony_ciSipHash key is derived from the master key) and added to the file 30462306a36Sopenharmony_cilogical block number mod 2^32 to produce a 32-bit IV. 30562306a36Sopenharmony_ci 30662306a36Sopenharmony_ciThis format is optimized for use with inline encryption hardware 30762306a36Sopenharmony_cicompliant with the eMMC v5.2 standard, which supports only 32 IV bits 30862306a36Sopenharmony_ciper I/O request and may have only a small number of keyslots. This 30962306a36Sopenharmony_ciformat results in some level of IV reuse, so it should only be used 31062306a36Sopenharmony_ciwhen necessary due to hardware limitations. 31162306a36Sopenharmony_ci 31262306a36Sopenharmony_ciKey identifiers 31362306a36Sopenharmony_ci--------------- 31462306a36Sopenharmony_ci 31562306a36Sopenharmony_ciFor master keys used for v2 encryption policies, a unique 16-byte "key 31662306a36Sopenharmony_ciidentifier" is also derived using the KDF. This value is stored in 31762306a36Sopenharmony_cithe clear, since it is needed to reliably identify the key itself. 31862306a36Sopenharmony_ci 31962306a36Sopenharmony_ciDirhash keys 32062306a36Sopenharmony_ci------------ 32162306a36Sopenharmony_ci 32262306a36Sopenharmony_ciFor directories that are indexed using a secret-keyed dirhash over the 32362306a36Sopenharmony_ciplaintext filenames, the KDF is also used to derive a 128-bit 32462306a36Sopenharmony_ciSipHash-2-4 key per directory in order to hash filenames. This works 32562306a36Sopenharmony_cijust like deriving a per-file encryption key, except that a different 32662306a36Sopenharmony_ciKDF context is used. Currently, only casefolded ("case-insensitive") 32762306a36Sopenharmony_ciencrypted directories use this style of hashing. 32862306a36Sopenharmony_ci 32962306a36Sopenharmony_ciEncryption modes and usage 33062306a36Sopenharmony_ci========================== 33162306a36Sopenharmony_ci 33262306a36Sopenharmony_cifscrypt allows one encryption mode to be specified for file contents 33362306a36Sopenharmony_ciand one encryption mode to be specified for filenames. Different 33462306a36Sopenharmony_cidirectory trees are permitted to use different encryption modes. 33562306a36Sopenharmony_ci 33662306a36Sopenharmony_ciSupported modes 33762306a36Sopenharmony_ci--------------- 33862306a36Sopenharmony_ci 33962306a36Sopenharmony_ciCurrently, the following pairs of encryption modes are supported: 34062306a36Sopenharmony_ci 34162306a36Sopenharmony_ci- AES-256-XTS for contents and AES-256-CTS-CBC for filenames 34262306a36Sopenharmony_ci- AES-256-XTS for contents and AES-256-HCTR2 for filenames 34362306a36Sopenharmony_ci- Adiantum for both contents and filenames 34462306a36Sopenharmony_ci- AES-128-CBC-ESSIV for contents and AES-128-CTS-CBC for filenames 34562306a36Sopenharmony_ci- SM4-XTS for contents and SM4-CTS-CBC for filenames 34662306a36Sopenharmony_ci 34762306a36Sopenharmony_ciAuthenticated encryption modes are not currently supported because of 34862306a36Sopenharmony_cithe difficulty of dealing with ciphertext expansion. Therefore, 34962306a36Sopenharmony_cicontents encryption uses a block cipher in `XTS mode 35062306a36Sopenharmony_ci<https://en.wikipedia.org/wiki/Disk_encryption_theory#XTS>`_ or 35162306a36Sopenharmony_ci`CBC-ESSIV mode 35262306a36Sopenharmony_ci<https://en.wikipedia.org/wiki/Disk_encryption_theory#Encrypted_salt-sector_initialization_vector_(ESSIV)>`_, 35362306a36Sopenharmony_cior a wide-block cipher. Filenames encryption uses a 35462306a36Sopenharmony_ciblock cipher in `CTS-CBC mode 35562306a36Sopenharmony_ci<https://en.wikipedia.org/wiki/Ciphertext_stealing>`_ or a wide-block 35662306a36Sopenharmony_cicipher. 35762306a36Sopenharmony_ci 35862306a36Sopenharmony_ciThe (AES-256-XTS, AES-256-CTS-CBC) pair is the recommended default. 35962306a36Sopenharmony_ciIt is also the only option that is *guaranteed* to always be supported 36062306a36Sopenharmony_ciif the kernel supports fscrypt at all; see `Kernel config options`_. 36162306a36Sopenharmony_ci 36262306a36Sopenharmony_ciThe (AES-256-XTS, AES-256-HCTR2) pair is also a good choice that 36362306a36Sopenharmony_ciupgrades the filenames encryption to use a wide-block cipher. (A 36462306a36Sopenharmony_ci*wide-block cipher*, also called a tweakable super-pseudorandom 36562306a36Sopenharmony_cipermutation, has the property that changing one bit scrambles the 36662306a36Sopenharmony_cientire result.) As described in `Filenames encryption`_, a wide-block 36762306a36Sopenharmony_cicipher is the ideal mode for the problem domain, though CTS-CBC is the 36862306a36Sopenharmony_ci"least bad" choice among the alternatives. For more information about 36962306a36Sopenharmony_ciHCTR2, see `the HCTR2 paper <https://eprint.iacr.org/2021/1441.pdf>`_. 37062306a36Sopenharmony_ci 37162306a36Sopenharmony_ciAdiantum is recommended on systems where AES is too slow due to lack 37262306a36Sopenharmony_ciof hardware acceleration for AES. Adiantum is a wide-block cipher 37362306a36Sopenharmony_cithat uses XChaCha12 and AES-256 as its underlying components. Most of 37462306a36Sopenharmony_cithe work is done by XChaCha12, which is much faster than AES when AES 37562306a36Sopenharmony_ciacceleration is unavailable. For more information about Adiantum, see 37662306a36Sopenharmony_ci`the Adiantum paper <https://eprint.iacr.org/2018/720.pdf>`_. 37762306a36Sopenharmony_ci 37862306a36Sopenharmony_ciThe (AES-128-CBC-ESSIV, AES-128-CTS-CBC) pair exists only to support 37962306a36Sopenharmony_cisystems whose only form of AES acceleration is an off-CPU crypto 38062306a36Sopenharmony_ciaccelerator such as CAAM or CESA that does not support XTS. 38162306a36Sopenharmony_ci 38262306a36Sopenharmony_ciThe remaining mode pairs are the "national pride ciphers": 38362306a36Sopenharmony_ci 38462306a36Sopenharmony_ci- (SM4-XTS, SM4-CTS-CBC) 38562306a36Sopenharmony_ci 38662306a36Sopenharmony_ciGenerally speaking, these ciphers aren't "bad" per se, but they 38762306a36Sopenharmony_cireceive limited security review compared to the usual choices such as 38862306a36Sopenharmony_ciAES and ChaCha. They also don't bring much new to the table. It is 38962306a36Sopenharmony_cisuggested to only use these ciphers where their use is mandated. 39062306a36Sopenharmony_ci 39162306a36Sopenharmony_ciKernel config options 39262306a36Sopenharmony_ci--------------------- 39362306a36Sopenharmony_ci 39462306a36Sopenharmony_ciEnabling fscrypt support (CONFIG_FS_ENCRYPTION) automatically pulls in 39562306a36Sopenharmony_cionly the basic support from the crypto API needed to use AES-256-XTS 39662306a36Sopenharmony_ciand AES-256-CTS-CBC encryption. For optimal performance, it is 39762306a36Sopenharmony_cistrongly recommended to also enable any available platform-specific 39862306a36Sopenharmony_cikconfig options that provide acceleration for the algorithm(s) you 39962306a36Sopenharmony_ciwish to use. Support for any "non-default" encryption modes typically 40062306a36Sopenharmony_cirequires extra kconfig options as well. 40162306a36Sopenharmony_ci 40262306a36Sopenharmony_ciBelow, some relevant options are listed by encryption mode. Note, 40362306a36Sopenharmony_ciacceleration options not listed below may be available for your 40462306a36Sopenharmony_ciplatform; refer to the kconfig menus. File contents encryption can 40562306a36Sopenharmony_cialso be configured to use inline encryption hardware instead of the 40662306a36Sopenharmony_cikernel crypto API (see `Inline encryption support`_); in that case, 40762306a36Sopenharmony_cithe file contents mode doesn't need to supported in the kernel crypto 40862306a36Sopenharmony_ciAPI, but the filenames mode still does. 40962306a36Sopenharmony_ci 41062306a36Sopenharmony_ci- AES-256-XTS and AES-256-CTS-CBC 41162306a36Sopenharmony_ci - Recommended: 41262306a36Sopenharmony_ci - arm64: CONFIG_CRYPTO_AES_ARM64_CE_BLK 41362306a36Sopenharmony_ci - x86: CONFIG_CRYPTO_AES_NI_INTEL 41462306a36Sopenharmony_ci 41562306a36Sopenharmony_ci- AES-256-HCTR2 41662306a36Sopenharmony_ci - Mandatory: 41762306a36Sopenharmony_ci - CONFIG_CRYPTO_HCTR2 41862306a36Sopenharmony_ci - Recommended: 41962306a36Sopenharmony_ci - arm64: CONFIG_CRYPTO_AES_ARM64_CE_BLK 42062306a36Sopenharmony_ci - arm64: CONFIG_CRYPTO_POLYVAL_ARM64_CE 42162306a36Sopenharmony_ci - x86: CONFIG_CRYPTO_AES_NI_INTEL 42262306a36Sopenharmony_ci - x86: CONFIG_CRYPTO_POLYVAL_CLMUL_NI 42362306a36Sopenharmony_ci 42462306a36Sopenharmony_ci- Adiantum 42562306a36Sopenharmony_ci - Mandatory: 42662306a36Sopenharmony_ci - CONFIG_CRYPTO_ADIANTUM 42762306a36Sopenharmony_ci - Recommended: 42862306a36Sopenharmony_ci - arm32: CONFIG_CRYPTO_CHACHA20_NEON 42962306a36Sopenharmony_ci - arm32: CONFIG_CRYPTO_NHPOLY1305_NEON 43062306a36Sopenharmony_ci - arm64: CONFIG_CRYPTO_CHACHA20_NEON 43162306a36Sopenharmony_ci - arm64: CONFIG_CRYPTO_NHPOLY1305_NEON 43262306a36Sopenharmony_ci - x86: CONFIG_CRYPTO_CHACHA20_X86_64 43362306a36Sopenharmony_ci - x86: CONFIG_CRYPTO_NHPOLY1305_SSE2 43462306a36Sopenharmony_ci - x86: CONFIG_CRYPTO_NHPOLY1305_AVX2 43562306a36Sopenharmony_ci 43662306a36Sopenharmony_ci- AES-128-CBC-ESSIV and AES-128-CTS-CBC: 43762306a36Sopenharmony_ci - Mandatory: 43862306a36Sopenharmony_ci - CONFIG_CRYPTO_ESSIV 43962306a36Sopenharmony_ci - CONFIG_CRYPTO_SHA256 or another SHA-256 implementation 44062306a36Sopenharmony_ci - Recommended: 44162306a36Sopenharmony_ci - AES-CBC acceleration 44262306a36Sopenharmony_ci 44362306a36Sopenharmony_cifscrypt also uses HMAC-SHA512 for key derivation, so enabling SHA-512 44462306a36Sopenharmony_ciacceleration is recommended: 44562306a36Sopenharmony_ci 44662306a36Sopenharmony_ci- SHA-512 44762306a36Sopenharmony_ci - Recommended: 44862306a36Sopenharmony_ci - arm64: CONFIG_CRYPTO_SHA512_ARM64_CE 44962306a36Sopenharmony_ci - x86: CONFIG_CRYPTO_SHA512_SSSE3 45062306a36Sopenharmony_ci 45162306a36Sopenharmony_ciContents encryption 45262306a36Sopenharmony_ci------------------- 45362306a36Sopenharmony_ci 45462306a36Sopenharmony_ciFor file contents, each filesystem block is encrypted independently. 45562306a36Sopenharmony_ciStarting from Linux kernel 5.5, encryption of filesystems with block 45662306a36Sopenharmony_cisize less than system's page size is supported. 45762306a36Sopenharmony_ci 45862306a36Sopenharmony_ciEach block's IV is set to the logical block number within the file as 45962306a36Sopenharmony_cia little endian number, except that: 46062306a36Sopenharmony_ci 46162306a36Sopenharmony_ci- With CBC mode encryption, ESSIV is also used. Specifically, each IV 46262306a36Sopenharmony_ci is encrypted with AES-256 where the AES-256 key is the SHA-256 hash 46362306a36Sopenharmony_ci of the file's data encryption key. 46462306a36Sopenharmony_ci 46562306a36Sopenharmony_ci- With `DIRECT_KEY policies`_, the file's nonce is appended to the IV. 46662306a36Sopenharmony_ci Currently this is only allowed with the Adiantum encryption mode. 46762306a36Sopenharmony_ci 46862306a36Sopenharmony_ci- With `IV_INO_LBLK_64 policies`_, the logical block number is limited 46962306a36Sopenharmony_ci to 32 bits and is placed in bits 0-31 of the IV. The inode number 47062306a36Sopenharmony_ci (which is also limited to 32 bits) is placed in bits 32-63. 47162306a36Sopenharmony_ci 47262306a36Sopenharmony_ci- With `IV_INO_LBLK_32 policies`_, the logical block number is limited 47362306a36Sopenharmony_ci to 32 bits and is placed in bits 0-31 of the IV. The inode number 47462306a36Sopenharmony_ci is then hashed and added mod 2^32. 47562306a36Sopenharmony_ci 47662306a36Sopenharmony_ciNote that because file logical block numbers are included in the IVs, 47762306a36Sopenharmony_cifilesystems must enforce that blocks are never shifted around within 47862306a36Sopenharmony_ciencrypted files, e.g. via "collapse range" or "insert range". 47962306a36Sopenharmony_ci 48062306a36Sopenharmony_ciFilenames encryption 48162306a36Sopenharmony_ci-------------------- 48262306a36Sopenharmony_ci 48362306a36Sopenharmony_ciFor filenames, each full filename is encrypted at once. Because of 48462306a36Sopenharmony_cithe requirements to retain support for efficient directory lookups and 48562306a36Sopenharmony_cifilenames of up to 255 bytes, the same IV is used for every filename 48662306a36Sopenharmony_ciin a directory. 48762306a36Sopenharmony_ci 48862306a36Sopenharmony_ciHowever, each encrypted directory still uses a unique key, or 48962306a36Sopenharmony_cialternatively has the file's nonce (for `DIRECT_KEY policies`_) or 49062306a36Sopenharmony_ciinode number (for `IV_INO_LBLK_64 policies`_) included in the IVs. 49162306a36Sopenharmony_ciThus, IV reuse is limited to within a single directory. 49262306a36Sopenharmony_ci 49362306a36Sopenharmony_ciWith CTS-CBC, the IV reuse means that when the plaintext filenames share a 49462306a36Sopenharmony_cicommon prefix at least as long as the cipher block size (16 bytes for AES), the 49562306a36Sopenharmony_cicorresponding encrypted filenames will also share a common prefix. This is 49662306a36Sopenharmony_ciundesirable. Adiantum and HCTR2 do not have this weakness, as they are 49762306a36Sopenharmony_ciwide-block encryption modes. 49862306a36Sopenharmony_ci 49962306a36Sopenharmony_ciAll supported filenames encryption modes accept any plaintext length 50062306a36Sopenharmony_ci>= 16 bytes; cipher block alignment is not required. However, 50162306a36Sopenharmony_cifilenames shorter than 16 bytes are NUL-padded to 16 bytes before 50262306a36Sopenharmony_cibeing encrypted. In addition, to reduce leakage of filename lengths 50362306a36Sopenharmony_civia their ciphertexts, all filenames are NUL-padded to the next 4, 8, 50462306a36Sopenharmony_ci16, or 32-byte boundary (configurable). 32 is recommended since this 50562306a36Sopenharmony_ciprovides the best confidentiality, at the cost of making directory 50662306a36Sopenharmony_cientries consume slightly more space. Note that since NUL (``\0``) is 50762306a36Sopenharmony_cinot otherwise a valid character in filenames, the padding will never 50862306a36Sopenharmony_ciproduce duplicate plaintexts. 50962306a36Sopenharmony_ci 51062306a36Sopenharmony_ciSymbolic link targets are considered a type of filename and are 51162306a36Sopenharmony_ciencrypted in the same way as filenames in directory entries, except 51262306a36Sopenharmony_cithat IV reuse is not a problem as each symlink has its own inode. 51362306a36Sopenharmony_ci 51462306a36Sopenharmony_ciUser API 51562306a36Sopenharmony_ci======== 51662306a36Sopenharmony_ci 51762306a36Sopenharmony_ciSetting an encryption policy 51862306a36Sopenharmony_ci---------------------------- 51962306a36Sopenharmony_ci 52062306a36Sopenharmony_ciFS_IOC_SET_ENCRYPTION_POLICY 52162306a36Sopenharmony_ci~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 52262306a36Sopenharmony_ci 52362306a36Sopenharmony_ciThe FS_IOC_SET_ENCRYPTION_POLICY ioctl sets an encryption policy on an 52462306a36Sopenharmony_ciempty directory or verifies that a directory or regular file already 52562306a36Sopenharmony_cihas the specified encryption policy. It takes in a pointer to 52662306a36Sopenharmony_cistruct fscrypt_policy_v1 or struct fscrypt_policy_v2, defined as 52762306a36Sopenharmony_cifollows:: 52862306a36Sopenharmony_ci 52962306a36Sopenharmony_ci #define FSCRYPT_POLICY_V1 0 53062306a36Sopenharmony_ci #define FSCRYPT_KEY_DESCRIPTOR_SIZE 8 53162306a36Sopenharmony_ci struct fscrypt_policy_v1 { 53262306a36Sopenharmony_ci __u8 version; 53362306a36Sopenharmony_ci __u8 contents_encryption_mode; 53462306a36Sopenharmony_ci __u8 filenames_encryption_mode; 53562306a36Sopenharmony_ci __u8 flags; 53662306a36Sopenharmony_ci __u8 master_key_descriptor[FSCRYPT_KEY_DESCRIPTOR_SIZE]; 53762306a36Sopenharmony_ci }; 53862306a36Sopenharmony_ci #define fscrypt_policy fscrypt_policy_v1 53962306a36Sopenharmony_ci 54062306a36Sopenharmony_ci #define FSCRYPT_POLICY_V2 2 54162306a36Sopenharmony_ci #define FSCRYPT_KEY_IDENTIFIER_SIZE 16 54262306a36Sopenharmony_ci struct fscrypt_policy_v2 { 54362306a36Sopenharmony_ci __u8 version; 54462306a36Sopenharmony_ci __u8 contents_encryption_mode; 54562306a36Sopenharmony_ci __u8 filenames_encryption_mode; 54662306a36Sopenharmony_ci __u8 flags; 54762306a36Sopenharmony_ci __u8 __reserved[4]; 54862306a36Sopenharmony_ci __u8 master_key_identifier[FSCRYPT_KEY_IDENTIFIER_SIZE]; 54962306a36Sopenharmony_ci }; 55062306a36Sopenharmony_ci 55162306a36Sopenharmony_ciThis structure must be initialized as follows: 55262306a36Sopenharmony_ci 55362306a36Sopenharmony_ci- ``version`` must be FSCRYPT_POLICY_V1 (0) if 55462306a36Sopenharmony_ci struct fscrypt_policy_v1 is used or FSCRYPT_POLICY_V2 (2) if 55562306a36Sopenharmony_ci struct fscrypt_policy_v2 is used. (Note: we refer to the original 55662306a36Sopenharmony_ci policy version as "v1", though its version code is really 0.) 55762306a36Sopenharmony_ci For new encrypted directories, use v2 policies. 55862306a36Sopenharmony_ci 55962306a36Sopenharmony_ci- ``contents_encryption_mode`` and ``filenames_encryption_mode`` must 56062306a36Sopenharmony_ci be set to constants from ``<linux/fscrypt.h>`` which identify the 56162306a36Sopenharmony_ci encryption modes to use. If unsure, use FSCRYPT_MODE_AES_256_XTS 56262306a36Sopenharmony_ci (1) for ``contents_encryption_mode`` and FSCRYPT_MODE_AES_256_CTS 56362306a36Sopenharmony_ci (4) for ``filenames_encryption_mode``. For details, see `Encryption 56462306a36Sopenharmony_ci modes and usage`_. 56562306a36Sopenharmony_ci 56662306a36Sopenharmony_ci v1 encryption policies only support three combinations of modes: 56762306a36Sopenharmony_ci (FSCRYPT_MODE_AES_256_XTS, FSCRYPT_MODE_AES_256_CTS), 56862306a36Sopenharmony_ci (FSCRYPT_MODE_AES_128_CBC, FSCRYPT_MODE_AES_128_CTS), and 56962306a36Sopenharmony_ci (FSCRYPT_MODE_ADIANTUM, FSCRYPT_MODE_ADIANTUM). v2 policies support 57062306a36Sopenharmony_ci all combinations documented in `Supported modes`_. 57162306a36Sopenharmony_ci 57262306a36Sopenharmony_ci- ``flags`` contains optional flags from ``<linux/fscrypt.h>``: 57362306a36Sopenharmony_ci 57462306a36Sopenharmony_ci - FSCRYPT_POLICY_FLAGS_PAD_*: The amount of NUL padding to use when 57562306a36Sopenharmony_ci encrypting filenames. If unsure, use FSCRYPT_POLICY_FLAGS_PAD_32 57662306a36Sopenharmony_ci (0x3). 57762306a36Sopenharmony_ci - FSCRYPT_POLICY_FLAG_DIRECT_KEY: See `DIRECT_KEY policies`_. 57862306a36Sopenharmony_ci - FSCRYPT_POLICY_FLAG_IV_INO_LBLK_64: See `IV_INO_LBLK_64 57962306a36Sopenharmony_ci policies`_. 58062306a36Sopenharmony_ci - FSCRYPT_POLICY_FLAG_IV_INO_LBLK_32: See `IV_INO_LBLK_32 58162306a36Sopenharmony_ci policies`_. 58262306a36Sopenharmony_ci 58362306a36Sopenharmony_ci v1 encryption policies only support the PAD_* and DIRECT_KEY flags. 58462306a36Sopenharmony_ci The other flags are only supported by v2 encryption policies. 58562306a36Sopenharmony_ci 58662306a36Sopenharmony_ci The DIRECT_KEY, IV_INO_LBLK_64, and IV_INO_LBLK_32 flags are 58762306a36Sopenharmony_ci mutually exclusive. 58862306a36Sopenharmony_ci 58962306a36Sopenharmony_ci- For v2 encryption policies, ``__reserved`` must be zeroed. 59062306a36Sopenharmony_ci 59162306a36Sopenharmony_ci- For v1 encryption policies, ``master_key_descriptor`` specifies how 59262306a36Sopenharmony_ci to find the master key in a keyring; see `Adding keys`_. It is up 59362306a36Sopenharmony_ci to userspace to choose a unique ``master_key_descriptor`` for each 59462306a36Sopenharmony_ci master key. The e4crypt and fscrypt tools use the first 8 bytes of 59562306a36Sopenharmony_ci ``SHA-512(SHA-512(master_key))``, but this particular scheme is not 59662306a36Sopenharmony_ci required. Also, the master key need not be in the keyring yet when 59762306a36Sopenharmony_ci FS_IOC_SET_ENCRYPTION_POLICY is executed. However, it must be added 59862306a36Sopenharmony_ci before any files can be created in the encrypted directory. 59962306a36Sopenharmony_ci 60062306a36Sopenharmony_ci For v2 encryption policies, ``master_key_descriptor`` has been 60162306a36Sopenharmony_ci replaced with ``master_key_identifier``, which is longer and cannot 60262306a36Sopenharmony_ci be arbitrarily chosen. Instead, the key must first be added using 60362306a36Sopenharmony_ci `FS_IOC_ADD_ENCRYPTION_KEY`_. Then, the ``key_spec.u.identifier`` 60462306a36Sopenharmony_ci the kernel returned in the struct fscrypt_add_key_arg must 60562306a36Sopenharmony_ci be used as the ``master_key_identifier`` in 60662306a36Sopenharmony_ci struct fscrypt_policy_v2. 60762306a36Sopenharmony_ci 60862306a36Sopenharmony_ciIf the file is not yet encrypted, then FS_IOC_SET_ENCRYPTION_POLICY 60962306a36Sopenharmony_civerifies that the file is an empty directory. If so, the specified 61062306a36Sopenharmony_ciencryption policy is assigned to the directory, turning it into an 61162306a36Sopenharmony_ciencrypted directory. After that, and after providing the 61262306a36Sopenharmony_cicorresponding master key as described in `Adding keys`_, all regular 61362306a36Sopenharmony_cifiles, directories (recursively), and symlinks created in the 61462306a36Sopenharmony_cidirectory will be encrypted, inheriting the same encryption policy. 61562306a36Sopenharmony_ciThe filenames in the directory's entries will be encrypted as well. 61662306a36Sopenharmony_ci 61762306a36Sopenharmony_ciAlternatively, if the file is already encrypted, then 61862306a36Sopenharmony_ciFS_IOC_SET_ENCRYPTION_POLICY validates that the specified encryption 61962306a36Sopenharmony_cipolicy exactly matches the actual one. If they match, then the ioctl 62062306a36Sopenharmony_cireturns 0. Otherwise, it fails with EEXIST. This works on both 62162306a36Sopenharmony_ciregular files and directories, including nonempty directories. 62262306a36Sopenharmony_ci 62362306a36Sopenharmony_ciWhen a v2 encryption policy is assigned to a directory, it is also 62462306a36Sopenharmony_cirequired that either the specified key has been added by the current 62562306a36Sopenharmony_ciuser or that the caller has CAP_FOWNER in the initial user namespace. 62662306a36Sopenharmony_ci(This is needed to prevent a user from encrypting their data with 62762306a36Sopenharmony_cianother user's key.) The key must remain added while 62862306a36Sopenharmony_ciFS_IOC_SET_ENCRYPTION_POLICY is executing. However, if the new 62962306a36Sopenharmony_ciencrypted directory does not need to be accessed immediately, then the 63062306a36Sopenharmony_cikey can be removed right away afterwards. 63162306a36Sopenharmony_ci 63262306a36Sopenharmony_ciNote that the ext4 filesystem does not allow the root directory to be 63362306a36Sopenharmony_ciencrypted, even if it is empty. Users who want to encrypt an entire 63462306a36Sopenharmony_cifilesystem with one key should consider using dm-crypt instead. 63562306a36Sopenharmony_ci 63662306a36Sopenharmony_ciFS_IOC_SET_ENCRYPTION_POLICY can fail with the following errors: 63762306a36Sopenharmony_ci 63862306a36Sopenharmony_ci- ``EACCES``: the file is not owned by the process's uid, nor does the 63962306a36Sopenharmony_ci process have the CAP_FOWNER capability in a namespace with the file 64062306a36Sopenharmony_ci owner's uid mapped 64162306a36Sopenharmony_ci- ``EEXIST``: the file is already encrypted with an encryption policy 64262306a36Sopenharmony_ci different from the one specified 64362306a36Sopenharmony_ci- ``EINVAL``: an invalid encryption policy was specified (invalid 64462306a36Sopenharmony_ci version, mode(s), or flags; or reserved bits were set); or a v1 64562306a36Sopenharmony_ci encryption policy was specified but the directory has the casefold 64662306a36Sopenharmony_ci flag enabled (casefolding is incompatible with v1 policies). 64762306a36Sopenharmony_ci- ``ENOKEY``: a v2 encryption policy was specified, but the key with 64862306a36Sopenharmony_ci the specified ``master_key_identifier`` has not been added, nor does 64962306a36Sopenharmony_ci the process have the CAP_FOWNER capability in the initial user 65062306a36Sopenharmony_ci namespace 65162306a36Sopenharmony_ci- ``ENOTDIR``: the file is unencrypted and is a regular file, not a 65262306a36Sopenharmony_ci directory 65362306a36Sopenharmony_ci- ``ENOTEMPTY``: the file is unencrypted and is a nonempty directory 65462306a36Sopenharmony_ci- ``ENOTTY``: this type of filesystem does not implement encryption 65562306a36Sopenharmony_ci- ``EOPNOTSUPP``: the kernel was not configured with encryption 65662306a36Sopenharmony_ci support for filesystems, or the filesystem superblock has not 65762306a36Sopenharmony_ci had encryption enabled on it. (For example, to use encryption on an 65862306a36Sopenharmony_ci ext4 filesystem, CONFIG_FS_ENCRYPTION must be enabled in the 65962306a36Sopenharmony_ci kernel config, and the superblock must have had the "encrypt" 66062306a36Sopenharmony_ci feature flag enabled using ``tune2fs -O encrypt`` or ``mkfs.ext4 -O 66162306a36Sopenharmony_ci encrypt``.) 66262306a36Sopenharmony_ci- ``EPERM``: this directory may not be encrypted, e.g. because it is 66362306a36Sopenharmony_ci the root directory of an ext4 filesystem 66462306a36Sopenharmony_ci- ``EROFS``: the filesystem is readonly 66562306a36Sopenharmony_ci 66662306a36Sopenharmony_ciGetting an encryption policy 66762306a36Sopenharmony_ci---------------------------- 66862306a36Sopenharmony_ci 66962306a36Sopenharmony_ciTwo ioctls are available to get a file's encryption policy: 67062306a36Sopenharmony_ci 67162306a36Sopenharmony_ci- `FS_IOC_GET_ENCRYPTION_POLICY_EX`_ 67262306a36Sopenharmony_ci- `FS_IOC_GET_ENCRYPTION_POLICY`_ 67362306a36Sopenharmony_ci 67462306a36Sopenharmony_ciThe extended (_EX) version of the ioctl is more general and is 67562306a36Sopenharmony_cirecommended to use when possible. However, on older kernels only the 67662306a36Sopenharmony_cioriginal ioctl is available. Applications should try the extended 67762306a36Sopenharmony_civersion, and if it fails with ENOTTY fall back to the original 67862306a36Sopenharmony_civersion. 67962306a36Sopenharmony_ci 68062306a36Sopenharmony_ciFS_IOC_GET_ENCRYPTION_POLICY_EX 68162306a36Sopenharmony_ci~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 68262306a36Sopenharmony_ci 68362306a36Sopenharmony_ciThe FS_IOC_GET_ENCRYPTION_POLICY_EX ioctl retrieves the encryption 68462306a36Sopenharmony_cipolicy, if any, for a directory or regular file. No additional 68562306a36Sopenharmony_cipermissions are required beyond the ability to open the file. It 68662306a36Sopenharmony_citakes in a pointer to struct fscrypt_get_policy_ex_arg, 68762306a36Sopenharmony_cidefined as follows:: 68862306a36Sopenharmony_ci 68962306a36Sopenharmony_ci struct fscrypt_get_policy_ex_arg { 69062306a36Sopenharmony_ci __u64 policy_size; /* input/output */ 69162306a36Sopenharmony_ci union { 69262306a36Sopenharmony_ci __u8 version; 69362306a36Sopenharmony_ci struct fscrypt_policy_v1 v1; 69462306a36Sopenharmony_ci struct fscrypt_policy_v2 v2; 69562306a36Sopenharmony_ci } policy; /* output */ 69662306a36Sopenharmony_ci }; 69762306a36Sopenharmony_ci 69862306a36Sopenharmony_ciThe caller must initialize ``policy_size`` to the size available for 69962306a36Sopenharmony_cithe policy struct, i.e. ``sizeof(arg.policy)``. 70062306a36Sopenharmony_ci 70162306a36Sopenharmony_ciOn success, the policy struct is returned in ``policy``, and its 70262306a36Sopenharmony_ciactual size is returned in ``policy_size``. ``policy.version`` should 70362306a36Sopenharmony_cibe checked to determine the version of policy returned. Note that the 70462306a36Sopenharmony_civersion code for the "v1" policy is actually 0 (FSCRYPT_POLICY_V1). 70562306a36Sopenharmony_ci 70662306a36Sopenharmony_ciFS_IOC_GET_ENCRYPTION_POLICY_EX can fail with the following errors: 70762306a36Sopenharmony_ci 70862306a36Sopenharmony_ci- ``EINVAL``: the file is encrypted, but it uses an unrecognized 70962306a36Sopenharmony_ci encryption policy version 71062306a36Sopenharmony_ci- ``ENODATA``: the file is not encrypted 71162306a36Sopenharmony_ci- ``ENOTTY``: this type of filesystem does not implement encryption, 71262306a36Sopenharmony_ci or this kernel is too old to support FS_IOC_GET_ENCRYPTION_POLICY_EX 71362306a36Sopenharmony_ci (try FS_IOC_GET_ENCRYPTION_POLICY instead) 71462306a36Sopenharmony_ci- ``EOPNOTSUPP``: the kernel was not configured with encryption 71562306a36Sopenharmony_ci support for this filesystem, or the filesystem superblock has not 71662306a36Sopenharmony_ci had encryption enabled on it 71762306a36Sopenharmony_ci- ``EOVERFLOW``: the file is encrypted and uses a recognized 71862306a36Sopenharmony_ci encryption policy version, but the policy struct does not fit into 71962306a36Sopenharmony_ci the provided buffer 72062306a36Sopenharmony_ci 72162306a36Sopenharmony_ciNote: if you only need to know whether a file is encrypted or not, on 72262306a36Sopenharmony_cimost filesystems it is also possible to use the FS_IOC_GETFLAGS ioctl 72362306a36Sopenharmony_ciand check for FS_ENCRYPT_FL, or to use the statx() system call and 72462306a36Sopenharmony_cicheck for STATX_ATTR_ENCRYPTED in stx_attributes. 72562306a36Sopenharmony_ci 72662306a36Sopenharmony_ciFS_IOC_GET_ENCRYPTION_POLICY 72762306a36Sopenharmony_ci~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 72862306a36Sopenharmony_ci 72962306a36Sopenharmony_ciThe FS_IOC_GET_ENCRYPTION_POLICY ioctl can also retrieve the 73062306a36Sopenharmony_ciencryption policy, if any, for a directory or regular file. However, 73162306a36Sopenharmony_ciunlike `FS_IOC_GET_ENCRYPTION_POLICY_EX`_, 73262306a36Sopenharmony_ciFS_IOC_GET_ENCRYPTION_POLICY only supports the original policy 73362306a36Sopenharmony_civersion. It takes in a pointer directly to struct fscrypt_policy_v1 73462306a36Sopenharmony_cirather than struct fscrypt_get_policy_ex_arg. 73562306a36Sopenharmony_ci 73662306a36Sopenharmony_ciThe error codes for FS_IOC_GET_ENCRYPTION_POLICY are the same as those 73762306a36Sopenharmony_cifor FS_IOC_GET_ENCRYPTION_POLICY_EX, except that 73862306a36Sopenharmony_ciFS_IOC_GET_ENCRYPTION_POLICY also returns ``EINVAL`` if the file is 73962306a36Sopenharmony_ciencrypted using a newer encryption policy version. 74062306a36Sopenharmony_ci 74162306a36Sopenharmony_ciGetting the per-filesystem salt 74262306a36Sopenharmony_ci------------------------------- 74362306a36Sopenharmony_ci 74462306a36Sopenharmony_ciSome filesystems, such as ext4 and F2FS, also support the deprecated 74562306a36Sopenharmony_ciioctl FS_IOC_GET_ENCRYPTION_PWSALT. This ioctl retrieves a randomly 74662306a36Sopenharmony_cigenerated 16-byte value stored in the filesystem superblock. This 74762306a36Sopenharmony_civalue is intended to used as a salt when deriving an encryption key 74862306a36Sopenharmony_cifrom a passphrase or other low-entropy user credential. 74962306a36Sopenharmony_ci 75062306a36Sopenharmony_ciFS_IOC_GET_ENCRYPTION_PWSALT is deprecated. Instead, prefer to 75162306a36Sopenharmony_cigenerate and manage any needed salt(s) in userspace. 75262306a36Sopenharmony_ci 75362306a36Sopenharmony_ciGetting a file's encryption nonce 75462306a36Sopenharmony_ci--------------------------------- 75562306a36Sopenharmony_ci 75662306a36Sopenharmony_ciSince Linux v5.7, the ioctl FS_IOC_GET_ENCRYPTION_NONCE is supported. 75762306a36Sopenharmony_ciOn encrypted files and directories it gets the inode's 16-byte nonce. 75862306a36Sopenharmony_ciOn unencrypted files and directories, it fails with ENODATA. 75962306a36Sopenharmony_ci 76062306a36Sopenharmony_ciThis ioctl can be useful for automated tests which verify that the 76162306a36Sopenharmony_ciencryption is being done correctly. It is not needed for normal use 76262306a36Sopenharmony_ciof fscrypt. 76362306a36Sopenharmony_ci 76462306a36Sopenharmony_ciAdding keys 76562306a36Sopenharmony_ci----------- 76662306a36Sopenharmony_ci 76762306a36Sopenharmony_ciFS_IOC_ADD_ENCRYPTION_KEY 76862306a36Sopenharmony_ci~~~~~~~~~~~~~~~~~~~~~~~~~ 76962306a36Sopenharmony_ci 77062306a36Sopenharmony_ciThe FS_IOC_ADD_ENCRYPTION_KEY ioctl adds a master encryption key to 77162306a36Sopenharmony_cithe filesystem, making all files on the filesystem which were 77262306a36Sopenharmony_ciencrypted using that key appear "unlocked", i.e. in plaintext form. 77362306a36Sopenharmony_ciIt can be executed on any file or directory on the target filesystem, 77462306a36Sopenharmony_cibut using the filesystem's root directory is recommended. It takes in 77562306a36Sopenharmony_cia pointer to struct fscrypt_add_key_arg, defined as follows:: 77662306a36Sopenharmony_ci 77762306a36Sopenharmony_ci struct fscrypt_add_key_arg { 77862306a36Sopenharmony_ci struct fscrypt_key_specifier key_spec; 77962306a36Sopenharmony_ci __u32 raw_size; 78062306a36Sopenharmony_ci __u32 key_id; 78162306a36Sopenharmony_ci __u32 __reserved[8]; 78262306a36Sopenharmony_ci __u8 raw[]; 78362306a36Sopenharmony_ci }; 78462306a36Sopenharmony_ci 78562306a36Sopenharmony_ci #define FSCRYPT_KEY_SPEC_TYPE_DESCRIPTOR 1 78662306a36Sopenharmony_ci #define FSCRYPT_KEY_SPEC_TYPE_IDENTIFIER 2 78762306a36Sopenharmony_ci 78862306a36Sopenharmony_ci struct fscrypt_key_specifier { 78962306a36Sopenharmony_ci __u32 type; /* one of FSCRYPT_KEY_SPEC_TYPE_* */ 79062306a36Sopenharmony_ci __u32 __reserved; 79162306a36Sopenharmony_ci union { 79262306a36Sopenharmony_ci __u8 __reserved[32]; /* reserve some extra space */ 79362306a36Sopenharmony_ci __u8 descriptor[FSCRYPT_KEY_DESCRIPTOR_SIZE]; 79462306a36Sopenharmony_ci __u8 identifier[FSCRYPT_KEY_IDENTIFIER_SIZE]; 79562306a36Sopenharmony_ci } u; 79662306a36Sopenharmony_ci }; 79762306a36Sopenharmony_ci 79862306a36Sopenharmony_ci struct fscrypt_provisioning_key_payload { 79962306a36Sopenharmony_ci __u32 type; 80062306a36Sopenharmony_ci __u32 __reserved; 80162306a36Sopenharmony_ci __u8 raw[]; 80262306a36Sopenharmony_ci }; 80362306a36Sopenharmony_ci 80462306a36Sopenharmony_cistruct fscrypt_add_key_arg must be zeroed, then initialized 80562306a36Sopenharmony_cias follows: 80662306a36Sopenharmony_ci 80762306a36Sopenharmony_ci- If the key is being added for use by v1 encryption policies, then 80862306a36Sopenharmony_ci ``key_spec.type`` must contain FSCRYPT_KEY_SPEC_TYPE_DESCRIPTOR, and 80962306a36Sopenharmony_ci ``key_spec.u.descriptor`` must contain the descriptor of the key 81062306a36Sopenharmony_ci being added, corresponding to the value in the 81162306a36Sopenharmony_ci ``master_key_descriptor`` field of struct fscrypt_policy_v1. 81262306a36Sopenharmony_ci To add this type of key, the calling process must have the 81362306a36Sopenharmony_ci CAP_SYS_ADMIN capability in the initial user namespace. 81462306a36Sopenharmony_ci 81562306a36Sopenharmony_ci Alternatively, if the key is being added for use by v2 encryption 81662306a36Sopenharmony_ci policies, then ``key_spec.type`` must contain 81762306a36Sopenharmony_ci FSCRYPT_KEY_SPEC_TYPE_IDENTIFIER, and ``key_spec.u.identifier`` is 81862306a36Sopenharmony_ci an *output* field which the kernel fills in with a cryptographic 81962306a36Sopenharmony_ci hash of the key. To add this type of key, the calling process does 82062306a36Sopenharmony_ci not need any privileges. However, the number of keys that can be 82162306a36Sopenharmony_ci added is limited by the user's quota for the keyrings service (see 82262306a36Sopenharmony_ci ``Documentation/security/keys/core.rst``). 82362306a36Sopenharmony_ci 82462306a36Sopenharmony_ci- ``raw_size`` must be the size of the ``raw`` key provided, in bytes. 82562306a36Sopenharmony_ci Alternatively, if ``key_id`` is nonzero, this field must be 0, since 82662306a36Sopenharmony_ci in that case the size is implied by the specified Linux keyring key. 82762306a36Sopenharmony_ci 82862306a36Sopenharmony_ci- ``key_id`` is 0 if the raw key is given directly in the ``raw`` 82962306a36Sopenharmony_ci field. Otherwise ``key_id`` is the ID of a Linux keyring key of 83062306a36Sopenharmony_ci type "fscrypt-provisioning" whose payload is 83162306a36Sopenharmony_ci struct fscrypt_provisioning_key_payload whose ``raw`` field contains 83262306a36Sopenharmony_ci the raw key and whose ``type`` field matches ``key_spec.type``. 83362306a36Sopenharmony_ci Since ``raw`` is variable-length, the total size of this key's 83462306a36Sopenharmony_ci payload must be ``sizeof(struct fscrypt_provisioning_key_payload)`` 83562306a36Sopenharmony_ci plus the raw key size. The process must have Search permission on 83662306a36Sopenharmony_ci this key. 83762306a36Sopenharmony_ci 83862306a36Sopenharmony_ci Most users should leave this 0 and specify the raw key directly. 83962306a36Sopenharmony_ci The support for specifying a Linux keyring key is intended mainly to 84062306a36Sopenharmony_ci allow re-adding keys after a filesystem is unmounted and re-mounted, 84162306a36Sopenharmony_ci without having to store the raw keys in userspace memory. 84262306a36Sopenharmony_ci 84362306a36Sopenharmony_ci- ``raw`` is a variable-length field which must contain the actual 84462306a36Sopenharmony_ci key, ``raw_size`` bytes long. Alternatively, if ``key_id`` is 84562306a36Sopenharmony_ci nonzero, then this field is unused. 84662306a36Sopenharmony_ci 84762306a36Sopenharmony_ciFor v2 policy keys, the kernel keeps track of which user (identified 84862306a36Sopenharmony_ciby effective user ID) added the key, and only allows the key to be 84962306a36Sopenharmony_ciremoved by that user --- or by "root", if they use 85062306a36Sopenharmony_ci`FS_IOC_REMOVE_ENCRYPTION_KEY_ALL_USERS`_. 85162306a36Sopenharmony_ci 85262306a36Sopenharmony_ciHowever, if another user has added the key, it may be desirable to 85362306a36Sopenharmony_ciprevent that other user from unexpectedly removing it. Therefore, 85462306a36Sopenharmony_ciFS_IOC_ADD_ENCRYPTION_KEY may also be used to add a v2 policy key 85562306a36Sopenharmony_ci*again*, even if it's already added by other user(s). In this case, 85662306a36Sopenharmony_ciFS_IOC_ADD_ENCRYPTION_KEY will just install a claim to the key for the 85762306a36Sopenharmony_cicurrent user, rather than actually add the key again (but the raw key 85862306a36Sopenharmony_cimust still be provided, as a proof of knowledge). 85962306a36Sopenharmony_ci 86062306a36Sopenharmony_ciFS_IOC_ADD_ENCRYPTION_KEY returns 0 if either the key or a claim to 86162306a36Sopenharmony_cithe key was either added or already exists. 86262306a36Sopenharmony_ci 86362306a36Sopenharmony_ciFS_IOC_ADD_ENCRYPTION_KEY can fail with the following errors: 86462306a36Sopenharmony_ci 86562306a36Sopenharmony_ci- ``EACCES``: FSCRYPT_KEY_SPEC_TYPE_DESCRIPTOR was specified, but the 86662306a36Sopenharmony_ci caller does not have the CAP_SYS_ADMIN capability in the initial 86762306a36Sopenharmony_ci user namespace; or the raw key was specified by Linux key ID but the 86862306a36Sopenharmony_ci process lacks Search permission on the key. 86962306a36Sopenharmony_ci- ``EDQUOT``: the key quota for this user would be exceeded by adding 87062306a36Sopenharmony_ci the key 87162306a36Sopenharmony_ci- ``EINVAL``: invalid key size or key specifier type, or reserved bits 87262306a36Sopenharmony_ci were set 87362306a36Sopenharmony_ci- ``EKEYREJECTED``: the raw key was specified by Linux key ID, but the 87462306a36Sopenharmony_ci key has the wrong type 87562306a36Sopenharmony_ci- ``ENOKEY``: the raw key was specified by Linux key ID, but no key 87662306a36Sopenharmony_ci exists with that ID 87762306a36Sopenharmony_ci- ``ENOTTY``: this type of filesystem does not implement encryption 87862306a36Sopenharmony_ci- ``EOPNOTSUPP``: the kernel was not configured with encryption 87962306a36Sopenharmony_ci support for this filesystem, or the filesystem superblock has not 88062306a36Sopenharmony_ci had encryption enabled on it 88162306a36Sopenharmony_ci 88262306a36Sopenharmony_ciLegacy method 88362306a36Sopenharmony_ci~~~~~~~~~~~~~ 88462306a36Sopenharmony_ci 88562306a36Sopenharmony_ciFor v1 encryption policies, a master encryption key can also be 88662306a36Sopenharmony_ciprovided by adding it to a process-subscribed keyring, e.g. to a 88762306a36Sopenharmony_cisession keyring, or to a user keyring if the user keyring is linked 88862306a36Sopenharmony_ciinto the session keyring. 88962306a36Sopenharmony_ci 89062306a36Sopenharmony_ciThis method is deprecated (and not supported for v2 encryption 89162306a36Sopenharmony_cipolicies) for several reasons. First, it cannot be used in 89262306a36Sopenharmony_cicombination with FS_IOC_REMOVE_ENCRYPTION_KEY (see `Removing keys`_), 89362306a36Sopenharmony_ciso for removing a key a workaround such as keyctl_unlink() in 89462306a36Sopenharmony_cicombination with ``sync; echo 2 > /proc/sys/vm/drop_caches`` would 89562306a36Sopenharmony_cihave to be used. Second, it doesn't match the fact that the 89662306a36Sopenharmony_cilocked/unlocked status of encrypted files (i.e. whether they appear to 89762306a36Sopenharmony_cibe in plaintext form or in ciphertext form) is global. This mismatch 89862306a36Sopenharmony_cihas caused much confusion as well as real problems when processes 89962306a36Sopenharmony_cirunning under different UIDs, such as a ``sudo`` command, need to 90062306a36Sopenharmony_ciaccess encrypted files. 90162306a36Sopenharmony_ci 90262306a36Sopenharmony_ciNevertheless, to add a key to one of the process-subscribed keyrings, 90362306a36Sopenharmony_cithe add_key() system call can be used (see: 90462306a36Sopenharmony_ci``Documentation/security/keys/core.rst``). The key type must be 90562306a36Sopenharmony_ci"logon"; keys of this type are kept in kernel memory and cannot be 90662306a36Sopenharmony_ciread back by userspace. The key description must be "fscrypt:" 90762306a36Sopenharmony_cifollowed by the 16-character lower case hex representation of the 90862306a36Sopenharmony_ci``master_key_descriptor`` that was set in the encryption policy. The 90962306a36Sopenharmony_cikey payload must conform to the following structure:: 91062306a36Sopenharmony_ci 91162306a36Sopenharmony_ci #define FSCRYPT_MAX_KEY_SIZE 64 91262306a36Sopenharmony_ci 91362306a36Sopenharmony_ci struct fscrypt_key { 91462306a36Sopenharmony_ci __u32 mode; 91562306a36Sopenharmony_ci __u8 raw[FSCRYPT_MAX_KEY_SIZE]; 91662306a36Sopenharmony_ci __u32 size; 91762306a36Sopenharmony_ci }; 91862306a36Sopenharmony_ci 91962306a36Sopenharmony_ci``mode`` is ignored; just set it to 0. The actual key is provided in 92062306a36Sopenharmony_ci``raw`` with ``size`` indicating its size in bytes. That is, the 92162306a36Sopenharmony_cibytes ``raw[0..size-1]`` (inclusive) are the actual key. 92262306a36Sopenharmony_ci 92362306a36Sopenharmony_ciThe key description prefix "fscrypt:" may alternatively be replaced 92462306a36Sopenharmony_ciwith a filesystem-specific prefix such as "ext4:". However, the 92562306a36Sopenharmony_cifilesystem-specific prefixes are deprecated and should not be used in 92662306a36Sopenharmony_cinew programs. 92762306a36Sopenharmony_ci 92862306a36Sopenharmony_ciRemoving keys 92962306a36Sopenharmony_ci------------- 93062306a36Sopenharmony_ci 93162306a36Sopenharmony_ciTwo ioctls are available for removing a key that was added by 93262306a36Sopenharmony_ci`FS_IOC_ADD_ENCRYPTION_KEY`_: 93362306a36Sopenharmony_ci 93462306a36Sopenharmony_ci- `FS_IOC_REMOVE_ENCRYPTION_KEY`_ 93562306a36Sopenharmony_ci- `FS_IOC_REMOVE_ENCRYPTION_KEY_ALL_USERS`_ 93662306a36Sopenharmony_ci 93762306a36Sopenharmony_ciThese two ioctls differ only in cases where v2 policy keys are added 93862306a36Sopenharmony_cior removed by non-root users. 93962306a36Sopenharmony_ci 94062306a36Sopenharmony_ciThese ioctls don't work on keys that were added via the legacy 94162306a36Sopenharmony_ciprocess-subscribed keyrings mechanism. 94262306a36Sopenharmony_ci 94362306a36Sopenharmony_ciBefore using these ioctls, read the `Kernel memory compromise`_ 94462306a36Sopenharmony_cisection for a discussion of the security goals and limitations of 94562306a36Sopenharmony_cithese ioctls. 94662306a36Sopenharmony_ci 94762306a36Sopenharmony_ciFS_IOC_REMOVE_ENCRYPTION_KEY 94862306a36Sopenharmony_ci~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 94962306a36Sopenharmony_ci 95062306a36Sopenharmony_ciThe FS_IOC_REMOVE_ENCRYPTION_KEY ioctl removes a claim to a master 95162306a36Sopenharmony_ciencryption key from the filesystem, and possibly removes the key 95262306a36Sopenharmony_ciitself. It can be executed on any file or directory on the target 95362306a36Sopenharmony_cifilesystem, but using the filesystem's root directory is recommended. 95462306a36Sopenharmony_ciIt takes in a pointer to struct fscrypt_remove_key_arg, defined 95562306a36Sopenharmony_cias follows:: 95662306a36Sopenharmony_ci 95762306a36Sopenharmony_ci struct fscrypt_remove_key_arg { 95862306a36Sopenharmony_ci struct fscrypt_key_specifier key_spec; 95962306a36Sopenharmony_ci #define FSCRYPT_KEY_REMOVAL_STATUS_FLAG_FILES_BUSY 0x00000001 96062306a36Sopenharmony_ci #define FSCRYPT_KEY_REMOVAL_STATUS_FLAG_OTHER_USERS 0x00000002 96162306a36Sopenharmony_ci __u32 removal_status_flags; /* output */ 96262306a36Sopenharmony_ci __u32 __reserved[5]; 96362306a36Sopenharmony_ci }; 96462306a36Sopenharmony_ci 96562306a36Sopenharmony_ciThis structure must be zeroed, then initialized as follows: 96662306a36Sopenharmony_ci 96762306a36Sopenharmony_ci- The key to remove is specified by ``key_spec``: 96862306a36Sopenharmony_ci 96962306a36Sopenharmony_ci - To remove a key used by v1 encryption policies, set 97062306a36Sopenharmony_ci ``key_spec.type`` to FSCRYPT_KEY_SPEC_TYPE_DESCRIPTOR and fill 97162306a36Sopenharmony_ci in ``key_spec.u.descriptor``. To remove this type of key, the 97262306a36Sopenharmony_ci calling process must have the CAP_SYS_ADMIN capability in the 97362306a36Sopenharmony_ci initial user namespace. 97462306a36Sopenharmony_ci 97562306a36Sopenharmony_ci - To remove a key used by v2 encryption policies, set 97662306a36Sopenharmony_ci ``key_spec.type`` to FSCRYPT_KEY_SPEC_TYPE_IDENTIFIER and fill 97762306a36Sopenharmony_ci in ``key_spec.u.identifier``. 97862306a36Sopenharmony_ci 97962306a36Sopenharmony_ciFor v2 policy keys, this ioctl is usable by non-root users. However, 98062306a36Sopenharmony_cito make this possible, it actually just removes the current user's 98162306a36Sopenharmony_ciclaim to the key, undoing a single call to FS_IOC_ADD_ENCRYPTION_KEY. 98262306a36Sopenharmony_ciOnly after all claims are removed is the key really removed. 98362306a36Sopenharmony_ci 98462306a36Sopenharmony_ciFor example, if FS_IOC_ADD_ENCRYPTION_KEY was called with uid 1000, 98562306a36Sopenharmony_cithen the key will be "claimed" by uid 1000, and 98662306a36Sopenharmony_ciFS_IOC_REMOVE_ENCRYPTION_KEY will only succeed as uid 1000. Or, if 98762306a36Sopenharmony_ciboth uids 1000 and 2000 added the key, then for each uid 98862306a36Sopenharmony_ciFS_IOC_REMOVE_ENCRYPTION_KEY will only remove their own claim. Only 98962306a36Sopenharmony_cionce *both* are removed is the key really removed. (Think of it like 99062306a36Sopenharmony_ciunlinking a file that may have hard links.) 99162306a36Sopenharmony_ci 99262306a36Sopenharmony_ciIf FS_IOC_REMOVE_ENCRYPTION_KEY really removes the key, it will also 99362306a36Sopenharmony_citry to "lock" all files that had been unlocked with the key. It won't 99462306a36Sopenharmony_cilock files that are still in-use, so this ioctl is expected to be used 99562306a36Sopenharmony_ciin cooperation with userspace ensuring that none of the files are 99662306a36Sopenharmony_cistill open. However, if necessary, this ioctl can be executed again 99762306a36Sopenharmony_cilater to retry locking any remaining files. 99862306a36Sopenharmony_ci 99962306a36Sopenharmony_ciFS_IOC_REMOVE_ENCRYPTION_KEY returns 0 if either the key was removed 100062306a36Sopenharmony_ci(but may still have files remaining to be locked), the user's claim to 100162306a36Sopenharmony_cithe key was removed, or the key was already removed but had files 100262306a36Sopenharmony_ciremaining to be the locked so the ioctl retried locking them. In any 100362306a36Sopenharmony_ciof these cases, ``removal_status_flags`` is filled in with the 100462306a36Sopenharmony_cifollowing informational status flags: 100562306a36Sopenharmony_ci 100662306a36Sopenharmony_ci- ``FSCRYPT_KEY_REMOVAL_STATUS_FLAG_FILES_BUSY``: set if some file(s) 100762306a36Sopenharmony_ci are still in-use. Not guaranteed to be set in the case where only 100862306a36Sopenharmony_ci the user's claim to the key was removed. 100962306a36Sopenharmony_ci- ``FSCRYPT_KEY_REMOVAL_STATUS_FLAG_OTHER_USERS``: set if only the 101062306a36Sopenharmony_ci user's claim to the key was removed, not the key itself 101162306a36Sopenharmony_ci 101262306a36Sopenharmony_ciFS_IOC_REMOVE_ENCRYPTION_KEY can fail with the following errors: 101362306a36Sopenharmony_ci 101462306a36Sopenharmony_ci- ``EACCES``: The FSCRYPT_KEY_SPEC_TYPE_DESCRIPTOR key specifier type 101562306a36Sopenharmony_ci was specified, but the caller does not have the CAP_SYS_ADMIN 101662306a36Sopenharmony_ci capability in the initial user namespace 101762306a36Sopenharmony_ci- ``EINVAL``: invalid key specifier type, or reserved bits were set 101862306a36Sopenharmony_ci- ``ENOKEY``: the key object was not found at all, i.e. it was never 101962306a36Sopenharmony_ci added in the first place or was already fully removed including all 102062306a36Sopenharmony_ci files locked; or, the user does not have a claim to the key (but 102162306a36Sopenharmony_ci someone else does). 102262306a36Sopenharmony_ci- ``ENOTTY``: this type of filesystem does not implement encryption 102362306a36Sopenharmony_ci- ``EOPNOTSUPP``: the kernel was not configured with encryption 102462306a36Sopenharmony_ci support for this filesystem, or the filesystem superblock has not 102562306a36Sopenharmony_ci had encryption enabled on it 102662306a36Sopenharmony_ci 102762306a36Sopenharmony_ciFS_IOC_REMOVE_ENCRYPTION_KEY_ALL_USERS 102862306a36Sopenharmony_ci~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 102962306a36Sopenharmony_ci 103062306a36Sopenharmony_ciFS_IOC_REMOVE_ENCRYPTION_KEY_ALL_USERS is exactly the same as 103162306a36Sopenharmony_ci`FS_IOC_REMOVE_ENCRYPTION_KEY`_, except that for v2 policy keys, the 103262306a36Sopenharmony_ciALL_USERS version of the ioctl will remove all users' claims to the 103362306a36Sopenharmony_cikey, not just the current user's. I.e., the key itself will always be 103462306a36Sopenharmony_ciremoved, no matter how many users have added it. This difference is 103562306a36Sopenharmony_cionly meaningful if non-root users are adding and removing keys. 103662306a36Sopenharmony_ci 103762306a36Sopenharmony_ciBecause of this, FS_IOC_REMOVE_ENCRYPTION_KEY_ALL_USERS also requires 103862306a36Sopenharmony_ci"root", namely the CAP_SYS_ADMIN capability in the initial user 103962306a36Sopenharmony_cinamespace. Otherwise it will fail with EACCES. 104062306a36Sopenharmony_ci 104162306a36Sopenharmony_ciGetting key status 104262306a36Sopenharmony_ci------------------ 104362306a36Sopenharmony_ci 104462306a36Sopenharmony_ciFS_IOC_GET_ENCRYPTION_KEY_STATUS 104562306a36Sopenharmony_ci~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 104662306a36Sopenharmony_ci 104762306a36Sopenharmony_ciThe FS_IOC_GET_ENCRYPTION_KEY_STATUS ioctl retrieves the status of a 104862306a36Sopenharmony_cimaster encryption key. It can be executed on any file or directory on 104962306a36Sopenharmony_cithe target filesystem, but using the filesystem's root directory is 105062306a36Sopenharmony_cirecommended. It takes in a pointer to 105162306a36Sopenharmony_cistruct fscrypt_get_key_status_arg, defined as follows:: 105262306a36Sopenharmony_ci 105362306a36Sopenharmony_ci struct fscrypt_get_key_status_arg { 105462306a36Sopenharmony_ci /* input */ 105562306a36Sopenharmony_ci struct fscrypt_key_specifier key_spec; 105662306a36Sopenharmony_ci __u32 __reserved[6]; 105762306a36Sopenharmony_ci 105862306a36Sopenharmony_ci /* output */ 105962306a36Sopenharmony_ci #define FSCRYPT_KEY_STATUS_ABSENT 1 106062306a36Sopenharmony_ci #define FSCRYPT_KEY_STATUS_PRESENT 2 106162306a36Sopenharmony_ci #define FSCRYPT_KEY_STATUS_INCOMPLETELY_REMOVED 3 106262306a36Sopenharmony_ci __u32 status; 106362306a36Sopenharmony_ci #define FSCRYPT_KEY_STATUS_FLAG_ADDED_BY_SELF 0x00000001 106462306a36Sopenharmony_ci __u32 status_flags; 106562306a36Sopenharmony_ci __u32 user_count; 106662306a36Sopenharmony_ci __u32 __out_reserved[13]; 106762306a36Sopenharmony_ci }; 106862306a36Sopenharmony_ci 106962306a36Sopenharmony_ciThe caller must zero all input fields, then fill in ``key_spec``: 107062306a36Sopenharmony_ci 107162306a36Sopenharmony_ci - To get the status of a key for v1 encryption policies, set 107262306a36Sopenharmony_ci ``key_spec.type`` to FSCRYPT_KEY_SPEC_TYPE_DESCRIPTOR and fill 107362306a36Sopenharmony_ci in ``key_spec.u.descriptor``. 107462306a36Sopenharmony_ci 107562306a36Sopenharmony_ci - To get the status of a key for v2 encryption policies, set 107662306a36Sopenharmony_ci ``key_spec.type`` to FSCRYPT_KEY_SPEC_TYPE_IDENTIFIER and fill 107762306a36Sopenharmony_ci in ``key_spec.u.identifier``. 107862306a36Sopenharmony_ci 107962306a36Sopenharmony_ciOn success, 0 is returned and the kernel fills in the output fields: 108062306a36Sopenharmony_ci 108162306a36Sopenharmony_ci- ``status`` indicates whether the key is absent, present, or 108262306a36Sopenharmony_ci incompletely removed. Incompletely removed means that the master 108362306a36Sopenharmony_ci secret has been removed, but some files are still in use; i.e., 108462306a36Sopenharmony_ci `FS_IOC_REMOVE_ENCRYPTION_KEY`_ returned 0 but set the informational 108562306a36Sopenharmony_ci status flag FSCRYPT_KEY_REMOVAL_STATUS_FLAG_FILES_BUSY. 108662306a36Sopenharmony_ci 108762306a36Sopenharmony_ci- ``status_flags`` can contain the following flags: 108862306a36Sopenharmony_ci 108962306a36Sopenharmony_ci - ``FSCRYPT_KEY_STATUS_FLAG_ADDED_BY_SELF`` indicates that the key 109062306a36Sopenharmony_ci has added by the current user. This is only set for keys 109162306a36Sopenharmony_ci identified by ``identifier`` rather than by ``descriptor``. 109262306a36Sopenharmony_ci 109362306a36Sopenharmony_ci- ``user_count`` specifies the number of users who have added the key. 109462306a36Sopenharmony_ci This is only set for keys identified by ``identifier`` rather than 109562306a36Sopenharmony_ci by ``descriptor``. 109662306a36Sopenharmony_ci 109762306a36Sopenharmony_ciFS_IOC_GET_ENCRYPTION_KEY_STATUS can fail with the following errors: 109862306a36Sopenharmony_ci 109962306a36Sopenharmony_ci- ``EINVAL``: invalid key specifier type, or reserved bits were set 110062306a36Sopenharmony_ci- ``ENOTTY``: this type of filesystem does not implement encryption 110162306a36Sopenharmony_ci- ``EOPNOTSUPP``: the kernel was not configured with encryption 110262306a36Sopenharmony_ci support for this filesystem, or the filesystem superblock has not 110362306a36Sopenharmony_ci had encryption enabled on it 110462306a36Sopenharmony_ci 110562306a36Sopenharmony_ciAmong other use cases, FS_IOC_GET_ENCRYPTION_KEY_STATUS can be useful 110662306a36Sopenharmony_cifor determining whether the key for a given encrypted directory needs 110762306a36Sopenharmony_cito be added before prompting the user for the passphrase needed to 110862306a36Sopenharmony_ciderive the key. 110962306a36Sopenharmony_ci 111062306a36Sopenharmony_ciFS_IOC_GET_ENCRYPTION_KEY_STATUS can only get the status of keys in 111162306a36Sopenharmony_cithe filesystem-level keyring, i.e. the keyring managed by 111262306a36Sopenharmony_ci`FS_IOC_ADD_ENCRYPTION_KEY`_ and `FS_IOC_REMOVE_ENCRYPTION_KEY`_. It 111362306a36Sopenharmony_cicannot get the status of a key that has only been added for use by v1 111462306a36Sopenharmony_ciencryption policies using the legacy mechanism involving 111562306a36Sopenharmony_ciprocess-subscribed keyrings. 111662306a36Sopenharmony_ci 111762306a36Sopenharmony_ciAccess semantics 111862306a36Sopenharmony_ci================ 111962306a36Sopenharmony_ci 112062306a36Sopenharmony_ciWith the key 112162306a36Sopenharmony_ci------------ 112262306a36Sopenharmony_ci 112362306a36Sopenharmony_ciWith the encryption key, encrypted regular files, directories, and 112462306a36Sopenharmony_cisymlinks behave very similarly to their unencrypted counterparts --- 112562306a36Sopenharmony_ciafter all, the encryption is intended to be transparent. However, 112662306a36Sopenharmony_ciastute users may notice some differences in behavior: 112762306a36Sopenharmony_ci 112862306a36Sopenharmony_ci- Unencrypted files, or files encrypted with a different encryption 112962306a36Sopenharmony_ci policy (i.e. different key, modes, or flags), cannot be renamed or 113062306a36Sopenharmony_ci linked into an encrypted directory; see `Encryption policy 113162306a36Sopenharmony_ci enforcement`_. Attempts to do so will fail with EXDEV. However, 113262306a36Sopenharmony_ci encrypted files can be renamed within an encrypted directory, or 113362306a36Sopenharmony_ci into an unencrypted directory. 113462306a36Sopenharmony_ci 113562306a36Sopenharmony_ci Note: "moving" an unencrypted file into an encrypted directory, e.g. 113662306a36Sopenharmony_ci with the `mv` program, is implemented in userspace by a copy 113762306a36Sopenharmony_ci followed by a delete. Be aware that the original unencrypted data 113862306a36Sopenharmony_ci may remain recoverable from free space on the disk; prefer to keep 113962306a36Sopenharmony_ci all files encrypted from the very beginning. The `shred` program 114062306a36Sopenharmony_ci may be used to overwrite the source files but isn't guaranteed to be 114162306a36Sopenharmony_ci effective on all filesystems and storage devices. 114262306a36Sopenharmony_ci 114362306a36Sopenharmony_ci- Direct I/O is supported on encrypted files only under some 114462306a36Sopenharmony_ci circumstances. For details, see `Direct I/O support`_. 114562306a36Sopenharmony_ci 114662306a36Sopenharmony_ci- The fallocate operations FALLOC_FL_COLLAPSE_RANGE and 114762306a36Sopenharmony_ci FALLOC_FL_INSERT_RANGE are not supported on encrypted files and will 114862306a36Sopenharmony_ci fail with EOPNOTSUPP. 114962306a36Sopenharmony_ci 115062306a36Sopenharmony_ci- Online defragmentation of encrypted files is not supported. The 115162306a36Sopenharmony_ci EXT4_IOC_MOVE_EXT and F2FS_IOC_MOVE_RANGE ioctls will fail with 115262306a36Sopenharmony_ci EOPNOTSUPP. 115362306a36Sopenharmony_ci 115462306a36Sopenharmony_ci- The ext4 filesystem does not support data journaling with encrypted 115562306a36Sopenharmony_ci regular files. It will fall back to ordered data mode instead. 115662306a36Sopenharmony_ci 115762306a36Sopenharmony_ci- DAX (Direct Access) is not supported on encrypted files. 115862306a36Sopenharmony_ci 115962306a36Sopenharmony_ci- The maximum length of an encrypted symlink is 2 bytes shorter than 116062306a36Sopenharmony_ci the maximum length of an unencrypted symlink. For example, on an 116162306a36Sopenharmony_ci EXT4 filesystem with a 4K block size, unencrypted symlinks can be up 116262306a36Sopenharmony_ci to 4095 bytes long, while encrypted symlinks can only be up to 4093 116362306a36Sopenharmony_ci bytes long (both lengths excluding the terminating null). 116462306a36Sopenharmony_ci 116562306a36Sopenharmony_ciNote that mmap *is* supported. This is possible because the pagecache 116662306a36Sopenharmony_cifor an encrypted file contains the plaintext, not the ciphertext. 116762306a36Sopenharmony_ci 116862306a36Sopenharmony_ciWithout the key 116962306a36Sopenharmony_ci--------------- 117062306a36Sopenharmony_ci 117162306a36Sopenharmony_ciSome filesystem operations may be performed on encrypted regular 117262306a36Sopenharmony_cifiles, directories, and symlinks even before their encryption key has 117362306a36Sopenharmony_cibeen added, or after their encryption key has been removed: 117462306a36Sopenharmony_ci 117562306a36Sopenharmony_ci- File metadata may be read, e.g. using stat(). 117662306a36Sopenharmony_ci 117762306a36Sopenharmony_ci- Directories may be listed, in which case the filenames will be 117862306a36Sopenharmony_ci listed in an encoded form derived from their ciphertext. The 117962306a36Sopenharmony_ci current encoding algorithm is described in `Filename hashing and 118062306a36Sopenharmony_ci encoding`_. The algorithm is subject to change, but it is 118162306a36Sopenharmony_ci guaranteed that the presented filenames will be no longer than 118262306a36Sopenharmony_ci NAME_MAX bytes, will not contain the ``/`` or ``\0`` characters, and 118362306a36Sopenharmony_ci will uniquely identify directory entries. 118462306a36Sopenharmony_ci 118562306a36Sopenharmony_ci The ``.`` and ``..`` directory entries are special. They are always 118662306a36Sopenharmony_ci present and are not encrypted or encoded. 118762306a36Sopenharmony_ci 118862306a36Sopenharmony_ci- Files may be deleted. That is, nondirectory files may be deleted 118962306a36Sopenharmony_ci with unlink() as usual, and empty directories may be deleted with 119062306a36Sopenharmony_ci rmdir() as usual. Therefore, ``rm`` and ``rm -r`` will work as 119162306a36Sopenharmony_ci expected. 119262306a36Sopenharmony_ci 119362306a36Sopenharmony_ci- Symlink targets may be read and followed, but they will be presented 119462306a36Sopenharmony_ci in encrypted form, similar to filenames in directories. Hence, they 119562306a36Sopenharmony_ci are unlikely to point to anywhere useful. 119662306a36Sopenharmony_ci 119762306a36Sopenharmony_ciWithout the key, regular files cannot be opened or truncated. 119862306a36Sopenharmony_ciAttempts to do so will fail with ENOKEY. This implies that any 119962306a36Sopenharmony_ciregular file operations that require a file descriptor, such as 120062306a36Sopenharmony_ciread(), write(), mmap(), fallocate(), and ioctl(), are also forbidden. 120162306a36Sopenharmony_ci 120262306a36Sopenharmony_ciAlso without the key, files of any type (including directories) cannot 120362306a36Sopenharmony_cibe created or linked into an encrypted directory, nor can a name in an 120462306a36Sopenharmony_ciencrypted directory be the source or target of a rename, nor can an 120562306a36Sopenharmony_ciO_TMPFILE temporary file be created in an encrypted directory. All 120662306a36Sopenharmony_cisuch operations will fail with ENOKEY. 120762306a36Sopenharmony_ci 120862306a36Sopenharmony_ciIt is not currently possible to backup and restore encrypted files 120962306a36Sopenharmony_ciwithout the encryption key. This would require special APIs which 121062306a36Sopenharmony_cihave not yet been implemented. 121162306a36Sopenharmony_ci 121262306a36Sopenharmony_ciEncryption policy enforcement 121362306a36Sopenharmony_ci============================= 121462306a36Sopenharmony_ci 121562306a36Sopenharmony_ciAfter an encryption policy has been set on a directory, all regular 121662306a36Sopenharmony_cifiles, directories, and symbolic links created in that directory 121762306a36Sopenharmony_ci(recursively) will inherit that encryption policy. Special files --- 121862306a36Sopenharmony_cithat is, named pipes, device nodes, and UNIX domain sockets --- will 121962306a36Sopenharmony_cinot be encrypted. 122062306a36Sopenharmony_ci 122162306a36Sopenharmony_ciExcept for those special files, it is forbidden to have unencrypted 122262306a36Sopenharmony_cifiles, or files encrypted with a different encryption policy, in an 122362306a36Sopenharmony_ciencrypted directory tree. Attempts to link or rename such a file into 122462306a36Sopenharmony_cian encrypted directory will fail with EXDEV. This is also enforced 122562306a36Sopenharmony_ciduring ->lookup() to provide limited protection against offline 122662306a36Sopenharmony_ciattacks that try to disable or downgrade encryption in known locations 122762306a36Sopenharmony_ciwhere applications may later write sensitive data. It is recommended 122862306a36Sopenharmony_cithat systems implementing a form of "verified boot" take advantage of 122962306a36Sopenharmony_cithis by validating all top-level encryption policies prior to access. 123062306a36Sopenharmony_ci 123162306a36Sopenharmony_ciInline encryption support 123262306a36Sopenharmony_ci========================= 123362306a36Sopenharmony_ci 123462306a36Sopenharmony_ciBy default, fscrypt uses the kernel crypto API for all cryptographic 123562306a36Sopenharmony_cioperations (other than HKDF, which fscrypt partially implements 123662306a36Sopenharmony_ciitself). The kernel crypto API supports hardware crypto accelerators, 123762306a36Sopenharmony_cibut only ones that work in the traditional way where all inputs and 123862306a36Sopenharmony_cioutputs (e.g. plaintexts and ciphertexts) are in memory. fscrypt can 123962306a36Sopenharmony_citake advantage of such hardware, but the traditional acceleration 124062306a36Sopenharmony_cimodel isn't particularly efficient and fscrypt hasn't been optimized 124162306a36Sopenharmony_cifor it. 124262306a36Sopenharmony_ci 124362306a36Sopenharmony_ciInstead, many newer systems (especially mobile SoCs) have *inline 124462306a36Sopenharmony_ciencryption hardware* that can encrypt/decrypt data while it is on its 124562306a36Sopenharmony_ciway to/from the storage device. Linux supports inline encryption 124662306a36Sopenharmony_cithrough a set of extensions to the block layer called *blk-crypto*. 124762306a36Sopenharmony_ciblk-crypto allows filesystems to attach encryption contexts to bios 124862306a36Sopenharmony_ci(I/O requests) to specify how the data will be encrypted or decrypted 124962306a36Sopenharmony_ciin-line. For more information about blk-crypto, see 125062306a36Sopenharmony_ci:ref:`Documentation/block/inline-encryption.rst <inline_encryption>`. 125162306a36Sopenharmony_ci 125262306a36Sopenharmony_ciOn supported filesystems (currently ext4 and f2fs), fscrypt can use 125362306a36Sopenharmony_ciblk-crypto instead of the kernel crypto API to encrypt/decrypt file 125462306a36Sopenharmony_cicontents. To enable this, set CONFIG_FS_ENCRYPTION_INLINE_CRYPT=y in 125562306a36Sopenharmony_cithe kernel configuration, and specify the "inlinecrypt" mount option 125662306a36Sopenharmony_ciwhen mounting the filesystem. 125762306a36Sopenharmony_ci 125862306a36Sopenharmony_ciNote that the "inlinecrypt" mount option just specifies to use inline 125962306a36Sopenharmony_ciencryption when possible; it doesn't force its use. fscrypt will 126062306a36Sopenharmony_cistill fall back to using the kernel crypto API on files where the 126162306a36Sopenharmony_ciinline encryption hardware doesn't have the needed crypto capabilities 126262306a36Sopenharmony_ci(e.g. support for the needed encryption algorithm and data unit size) 126362306a36Sopenharmony_ciand where blk-crypto-fallback is unusable. (For blk-crypto-fallback 126462306a36Sopenharmony_cito be usable, it must be enabled in the kernel configuration with 126562306a36Sopenharmony_ciCONFIG_BLK_INLINE_ENCRYPTION_FALLBACK=y.) 126662306a36Sopenharmony_ci 126762306a36Sopenharmony_ciCurrently fscrypt always uses the filesystem block size (which is 126862306a36Sopenharmony_ciusually 4096 bytes) as the data unit size. Therefore, it can only use 126962306a36Sopenharmony_ciinline encryption hardware that supports that data unit size. 127062306a36Sopenharmony_ci 127162306a36Sopenharmony_ciInline encryption doesn't affect the ciphertext or other aspects of 127262306a36Sopenharmony_cithe on-disk format, so users may freely switch back and forth between 127362306a36Sopenharmony_ciusing "inlinecrypt" and not using "inlinecrypt". 127462306a36Sopenharmony_ci 127562306a36Sopenharmony_ciDirect I/O support 127662306a36Sopenharmony_ci================== 127762306a36Sopenharmony_ci 127862306a36Sopenharmony_ciFor direct I/O on an encrypted file to work, the following conditions 127962306a36Sopenharmony_cimust be met (in addition to the conditions for direct I/O on an 128062306a36Sopenharmony_ciunencrypted file): 128162306a36Sopenharmony_ci 128262306a36Sopenharmony_ci* The file must be using inline encryption. Usually this means that 128362306a36Sopenharmony_ci the filesystem must be mounted with ``-o inlinecrypt`` and inline 128462306a36Sopenharmony_ci encryption hardware must be present. However, a software fallback 128562306a36Sopenharmony_ci is also available. For details, see `Inline encryption support`_. 128662306a36Sopenharmony_ci 128762306a36Sopenharmony_ci* The I/O request must be fully aligned to the filesystem block size. 128862306a36Sopenharmony_ci This means that the file position the I/O is targeting, the lengths 128962306a36Sopenharmony_ci of all I/O segments, and the memory addresses of all I/O buffers 129062306a36Sopenharmony_ci must be multiples of this value. Note that the filesystem block 129162306a36Sopenharmony_ci size may be greater than the logical block size of the block device. 129262306a36Sopenharmony_ci 129362306a36Sopenharmony_ciIf either of the above conditions is not met, then direct I/O on the 129462306a36Sopenharmony_ciencrypted file will fall back to buffered I/O. 129562306a36Sopenharmony_ci 129662306a36Sopenharmony_ciImplementation details 129762306a36Sopenharmony_ci====================== 129862306a36Sopenharmony_ci 129962306a36Sopenharmony_ciEncryption context 130062306a36Sopenharmony_ci------------------ 130162306a36Sopenharmony_ci 130262306a36Sopenharmony_ciAn encryption policy is represented on-disk by 130362306a36Sopenharmony_cistruct fscrypt_context_v1 or struct fscrypt_context_v2. It is up to 130462306a36Sopenharmony_ciindividual filesystems to decide where to store it, but normally it 130562306a36Sopenharmony_ciwould be stored in a hidden extended attribute. It should *not* be 130662306a36Sopenharmony_ciexposed by the xattr-related system calls such as getxattr() and 130762306a36Sopenharmony_cisetxattr() because of the special semantics of the encryption xattr. 130862306a36Sopenharmony_ci(In particular, there would be much confusion if an encryption policy 130962306a36Sopenharmony_ciwere to be added to or removed from anything other than an empty 131062306a36Sopenharmony_cidirectory.) These structs are defined as follows:: 131162306a36Sopenharmony_ci 131262306a36Sopenharmony_ci #define FSCRYPT_FILE_NONCE_SIZE 16 131362306a36Sopenharmony_ci 131462306a36Sopenharmony_ci #define FSCRYPT_KEY_DESCRIPTOR_SIZE 8 131562306a36Sopenharmony_ci struct fscrypt_context_v1 { 131662306a36Sopenharmony_ci u8 version; 131762306a36Sopenharmony_ci u8 contents_encryption_mode; 131862306a36Sopenharmony_ci u8 filenames_encryption_mode; 131962306a36Sopenharmony_ci u8 flags; 132062306a36Sopenharmony_ci u8 master_key_descriptor[FSCRYPT_KEY_DESCRIPTOR_SIZE]; 132162306a36Sopenharmony_ci u8 nonce[FSCRYPT_FILE_NONCE_SIZE]; 132262306a36Sopenharmony_ci }; 132362306a36Sopenharmony_ci 132462306a36Sopenharmony_ci #define FSCRYPT_KEY_IDENTIFIER_SIZE 16 132562306a36Sopenharmony_ci struct fscrypt_context_v2 { 132662306a36Sopenharmony_ci u8 version; 132762306a36Sopenharmony_ci u8 contents_encryption_mode; 132862306a36Sopenharmony_ci u8 filenames_encryption_mode; 132962306a36Sopenharmony_ci u8 flags; 133062306a36Sopenharmony_ci u8 __reserved[4]; 133162306a36Sopenharmony_ci u8 master_key_identifier[FSCRYPT_KEY_IDENTIFIER_SIZE]; 133262306a36Sopenharmony_ci u8 nonce[FSCRYPT_FILE_NONCE_SIZE]; 133362306a36Sopenharmony_ci }; 133462306a36Sopenharmony_ci 133562306a36Sopenharmony_ciThe context structs contain the same information as the corresponding 133662306a36Sopenharmony_cipolicy structs (see `Setting an encryption policy`_), except that the 133762306a36Sopenharmony_cicontext structs also contain a nonce. The nonce is randomly generated 133862306a36Sopenharmony_ciby the kernel and is used as KDF input or as a tweak to cause 133962306a36Sopenharmony_cidifferent files to be encrypted differently; see `Per-file encryption 134062306a36Sopenharmony_cikeys`_ and `DIRECT_KEY policies`_. 134162306a36Sopenharmony_ci 134262306a36Sopenharmony_ciData path changes 134362306a36Sopenharmony_ci----------------- 134462306a36Sopenharmony_ci 134562306a36Sopenharmony_ciWhen inline encryption is used, filesystems just need to associate 134662306a36Sopenharmony_ciencryption contexts with bios to specify how the block layer or the 134762306a36Sopenharmony_ciinline encryption hardware will encrypt/decrypt the file contents. 134862306a36Sopenharmony_ci 134962306a36Sopenharmony_ciWhen inline encryption isn't used, filesystems must encrypt/decrypt 135062306a36Sopenharmony_cithe file contents themselves, as described below: 135162306a36Sopenharmony_ci 135262306a36Sopenharmony_ciFor the read path (->read_folio()) of regular files, filesystems can 135362306a36Sopenharmony_ciread the ciphertext into the page cache and decrypt it in-place. The 135462306a36Sopenharmony_cifolio lock must be held until decryption has finished, to prevent the 135562306a36Sopenharmony_cifolio from becoming visible to userspace prematurely. 135662306a36Sopenharmony_ci 135762306a36Sopenharmony_ciFor the write path (->writepage()) of regular files, filesystems 135862306a36Sopenharmony_cicannot encrypt data in-place in the page cache, since the cached 135962306a36Sopenharmony_ciplaintext must be preserved. Instead, filesystems must encrypt into a 136062306a36Sopenharmony_citemporary buffer or "bounce page", then write out the temporary 136162306a36Sopenharmony_cibuffer. Some filesystems, such as UBIFS, already use temporary 136262306a36Sopenharmony_cibuffers regardless of encryption. Other filesystems, such as ext4 and 136362306a36Sopenharmony_ciF2FS, have to allocate bounce pages specially for encryption. 136462306a36Sopenharmony_ci 136562306a36Sopenharmony_ciFilename hashing and encoding 136662306a36Sopenharmony_ci----------------------------- 136762306a36Sopenharmony_ci 136862306a36Sopenharmony_ciModern filesystems accelerate directory lookups by using indexed 136962306a36Sopenharmony_cidirectories. An indexed directory is organized as a tree keyed by 137062306a36Sopenharmony_cifilename hashes. When a ->lookup() is requested, the filesystem 137162306a36Sopenharmony_cinormally hashes the filename being looked up so that it can quickly 137262306a36Sopenharmony_cifind the corresponding directory entry, if any. 137362306a36Sopenharmony_ci 137462306a36Sopenharmony_ciWith encryption, lookups must be supported and efficient both with and 137562306a36Sopenharmony_ciwithout the encryption key. Clearly, it would not work to hash the 137662306a36Sopenharmony_ciplaintext filenames, since the plaintext filenames are unavailable 137762306a36Sopenharmony_ciwithout the key. (Hashing the plaintext filenames would also make it 137862306a36Sopenharmony_ciimpossible for the filesystem's fsck tool to optimize encrypted 137962306a36Sopenharmony_cidirectories.) Instead, filesystems hash the ciphertext filenames, 138062306a36Sopenharmony_cii.e. the bytes actually stored on-disk in the directory entries. When 138162306a36Sopenharmony_ciasked to do a ->lookup() with the key, the filesystem just encrypts 138262306a36Sopenharmony_cithe user-supplied name to get the ciphertext. 138362306a36Sopenharmony_ci 138462306a36Sopenharmony_ciLookups without the key are more complicated. The raw ciphertext may 138562306a36Sopenharmony_cicontain the ``\0`` and ``/`` characters, which are illegal in 138662306a36Sopenharmony_cifilenames. Therefore, readdir() must base64url-encode the ciphertext 138762306a36Sopenharmony_cifor presentation. For most filenames, this works fine; on ->lookup(), 138862306a36Sopenharmony_cithe filesystem just base64url-decodes the user-supplied name to get 138962306a36Sopenharmony_ciback to the raw ciphertext. 139062306a36Sopenharmony_ci 139162306a36Sopenharmony_ciHowever, for very long filenames, base64url encoding would cause the 139262306a36Sopenharmony_cifilename length to exceed NAME_MAX. To prevent this, readdir() 139362306a36Sopenharmony_ciactually presents long filenames in an abbreviated form which encodes 139462306a36Sopenharmony_cia strong "hash" of the ciphertext filename, along with the optional 139562306a36Sopenharmony_cifilesystem-specific hash(es) needed for directory lookups. This 139662306a36Sopenharmony_ciallows the filesystem to still, with a high degree of confidence, map 139762306a36Sopenharmony_cithe filename given in ->lookup() back to a particular directory entry 139862306a36Sopenharmony_cithat was previously listed by readdir(). See 139962306a36Sopenharmony_cistruct fscrypt_nokey_name in the source for more details. 140062306a36Sopenharmony_ci 140162306a36Sopenharmony_ciNote that the precise way that filenames are presented to userspace 140262306a36Sopenharmony_ciwithout the key is subject to change in the future. It is only meant 140362306a36Sopenharmony_cias a way to temporarily present valid filenames so that commands like 140462306a36Sopenharmony_ci``rm -r`` work as expected on encrypted directories. 140562306a36Sopenharmony_ci 140662306a36Sopenharmony_ciTests 140762306a36Sopenharmony_ci===== 140862306a36Sopenharmony_ci 140962306a36Sopenharmony_ciTo test fscrypt, use xfstests, which is Linux's de facto standard 141062306a36Sopenharmony_cifilesystem test suite. First, run all the tests in the "encrypt" 141162306a36Sopenharmony_cigroup on the relevant filesystem(s). One can also run the tests 141262306a36Sopenharmony_ciwith the 'inlinecrypt' mount option to test the implementation for 141362306a36Sopenharmony_ciinline encryption support. For example, to test ext4 and 141462306a36Sopenharmony_cif2fs encryption using `kvm-xfstests 141562306a36Sopenharmony_ci<https://github.com/tytso/xfstests-bld/blob/master/Documentation/kvm-quickstart.md>`_:: 141662306a36Sopenharmony_ci 141762306a36Sopenharmony_ci kvm-xfstests -c ext4,f2fs -g encrypt 141862306a36Sopenharmony_ci kvm-xfstests -c ext4,f2fs -g encrypt -m inlinecrypt 141962306a36Sopenharmony_ci 142062306a36Sopenharmony_ciUBIFS encryption can also be tested this way, but it should be done in 142162306a36Sopenharmony_cia separate command, and it takes some time for kvm-xfstests to set up 142262306a36Sopenharmony_ciemulated UBI volumes:: 142362306a36Sopenharmony_ci 142462306a36Sopenharmony_ci kvm-xfstests -c ubifs -g encrypt 142562306a36Sopenharmony_ci 142662306a36Sopenharmony_ciNo tests should fail. However, tests that use non-default encryption 142762306a36Sopenharmony_cimodes (e.g. generic/549 and generic/550) will be skipped if the needed 142862306a36Sopenharmony_cialgorithms were not built into the kernel's crypto API. Also, tests 142962306a36Sopenharmony_cithat access the raw block device (e.g. generic/399, generic/548, 143062306a36Sopenharmony_cigeneric/549, generic/550) will be skipped on UBIFS. 143162306a36Sopenharmony_ci 143262306a36Sopenharmony_ciBesides running the "encrypt" group tests, for ext4 and f2fs it's also 143362306a36Sopenharmony_cipossible to run most xfstests with the "test_dummy_encryption" mount 143462306a36Sopenharmony_cioption. This option causes all new files to be automatically 143562306a36Sopenharmony_ciencrypted with a dummy key, without having to make any API calls. 143662306a36Sopenharmony_ciThis tests the encrypted I/O paths more thoroughly. To do this with 143762306a36Sopenharmony_cikvm-xfstests, use the "encrypt" filesystem configuration:: 143862306a36Sopenharmony_ci 143962306a36Sopenharmony_ci kvm-xfstests -c ext4/encrypt,f2fs/encrypt -g auto 144062306a36Sopenharmony_ci kvm-xfstests -c ext4/encrypt,f2fs/encrypt -g auto -m inlinecrypt 144162306a36Sopenharmony_ci 144262306a36Sopenharmony_ciBecause this runs many more tests than "-g encrypt" does, it takes 144362306a36Sopenharmony_cimuch longer to run; so also consider using `gce-xfstests 144462306a36Sopenharmony_ci<https://github.com/tytso/xfstests-bld/blob/master/Documentation/gce-xfstests.md>`_ 144562306a36Sopenharmony_ciinstead of kvm-xfstests:: 144662306a36Sopenharmony_ci 144762306a36Sopenharmony_ci gce-xfstests -c ext4/encrypt,f2fs/encrypt -g auto 144862306a36Sopenharmony_ci gce-xfstests -c ext4/encrypt,f2fs/encrypt -g auto -m inlinecrypt 1449