18c2ecf20Sopenharmony_ci===================================== 28c2ecf20Sopenharmony_ciFilesystem-level encryption (fscrypt) 38c2ecf20Sopenharmony_ci===================================== 48c2ecf20Sopenharmony_ci 58c2ecf20Sopenharmony_ciIntroduction 68c2ecf20Sopenharmony_ci============ 78c2ecf20Sopenharmony_ci 88c2ecf20Sopenharmony_cifscrypt is a library which filesystems can hook into to support 98c2ecf20Sopenharmony_citransparent encryption of files and directories. 108c2ecf20Sopenharmony_ci 118c2ecf20Sopenharmony_ciNote: "fscrypt" in this document refers to the kernel-level portion, 128c2ecf20Sopenharmony_ciimplemented in ``fs/crypto/``, as opposed to the userspace tool 138c2ecf20Sopenharmony_ci`fscrypt <https://github.com/google/fscrypt>`_. This document only 148c2ecf20Sopenharmony_cicovers the kernel-level portion. For command-line examples of how to 158c2ecf20Sopenharmony_ciuse encryption, see the documentation for the userspace tool `fscrypt 168c2ecf20Sopenharmony_ci<https://github.com/google/fscrypt>`_. Also, it is recommended to use 178c2ecf20Sopenharmony_cithe fscrypt userspace tool, or other existing userspace tools such as 188c2ecf20Sopenharmony_ci`fscryptctl <https://github.com/google/fscryptctl>`_ or `Android's key 198c2ecf20Sopenharmony_cimanagement system 208c2ecf20Sopenharmony_ci<https://source.android.com/security/encryption/file-based>`_, over 218c2ecf20Sopenharmony_ciusing the kernel's API directly. Using existing tools reduces the 228c2ecf20Sopenharmony_cichance of introducing your own security bugs. (Nevertheless, for 238c2ecf20Sopenharmony_cicompleteness this documentation covers the kernel's API anyway.) 248c2ecf20Sopenharmony_ci 258c2ecf20Sopenharmony_ciUnlike dm-crypt, fscrypt operates at the filesystem level rather than 268c2ecf20Sopenharmony_ciat the block device level. This allows it to encrypt different files 278c2ecf20Sopenharmony_ciwith different keys and to have unencrypted files on the same 288c2ecf20Sopenharmony_cifilesystem. This is useful for multi-user systems where each user's 298c2ecf20Sopenharmony_cidata-at-rest needs to be cryptographically isolated from the others. 308c2ecf20Sopenharmony_ciHowever, except for filenames, fscrypt does not encrypt filesystem 318c2ecf20Sopenharmony_cimetadata. 328c2ecf20Sopenharmony_ci 338c2ecf20Sopenharmony_ciUnlike eCryptfs, which is a stacked filesystem, fscrypt is integrated 348c2ecf20Sopenharmony_cidirectly into supported filesystems --- currently ext4, F2FS, and 358c2ecf20Sopenharmony_ciUBIFS. This allows encrypted files to be read and written without 368c2ecf20Sopenharmony_cicaching both the decrypted and encrypted pages in the pagecache, 378c2ecf20Sopenharmony_cithereby nearly halving the memory used and bringing it in line with 388c2ecf20Sopenharmony_ciunencrypted files. Similarly, half as many dentries and inodes are 398c2ecf20Sopenharmony_cineeded. eCryptfs also limits encrypted filenames to 143 bytes, 408c2ecf20Sopenharmony_cicausing application compatibility issues; fscrypt allows the full 255 418c2ecf20Sopenharmony_cibytes (NAME_MAX). Finally, unlike eCryptfs, the fscrypt API can be 428c2ecf20Sopenharmony_ciused by unprivileged users, with no need to mount anything. 438c2ecf20Sopenharmony_ci 448c2ecf20Sopenharmony_cifscrypt does not support encrypting files in-place. Instead, it 458c2ecf20Sopenharmony_cisupports marking an empty directory as encrypted. Then, after 468c2ecf20Sopenharmony_ciuserspace provides the key, all regular files, directories, and 478c2ecf20Sopenharmony_cisymbolic links created in that directory tree are transparently 488c2ecf20Sopenharmony_ciencrypted. 498c2ecf20Sopenharmony_ci 508c2ecf20Sopenharmony_ciThreat model 518c2ecf20Sopenharmony_ci============ 528c2ecf20Sopenharmony_ci 538c2ecf20Sopenharmony_ciOffline attacks 548c2ecf20Sopenharmony_ci--------------- 558c2ecf20Sopenharmony_ci 568c2ecf20Sopenharmony_ciProvided that userspace chooses a strong encryption key, fscrypt 578c2ecf20Sopenharmony_ciprotects the confidentiality of file contents and filenames in the 588c2ecf20Sopenharmony_cievent of a single point-in-time permanent offline compromise of the 598c2ecf20Sopenharmony_ciblock device content. fscrypt does not protect the confidentiality of 608c2ecf20Sopenharmony_cinon-filename metadata, e.g. file sizes, file permissions, file 618c2ecf20Sopenharmony_citimestamps, and extended attributes. Also, the existence and location 628c2ecf20Sopenharmony_ciof holes (unallocated blocks which logically contain all zeroes) in 638c2ecf20Sopenharmony_cifiles is not protected. 648c2ecf20Sopenharmony_ci 658c2ecf20Sopenharmony_cifscrypt is not guaranteed to protect confidentiality or authenticity 668c2ecf20Sopenharmony_ciif an attacker is able to manipulate the filesystem offline prior to 678c2ecf20Sopenharmony_cian authorized user later accessing the filesystem. 688c2ecf20Sopenharmony_ci 698c2ecf20Sopenharmony_ciOnline attacks 708c2ecf20Sopenharmony_ci-------------- 718c2ecf20Sopenharmony_ci 728c2ecf20Sopenharmony_cifscrypt (and storage encryption in general) can only provide limited 738c2ecf20Sopenharmony_ciprotection, if any at all, against online attacks. In detail: 748c2ecf20Sopenharmony_ci 758c2ecf20Sopenharmony_ciSide-channel attacks 768c2ecf20Sopenharmony_ci~~~~~~~~~~~~~~~~~~~~ 778c2ecf20Sopenharmony_ci 788c2ecf20Sopenharmony_cifscrypt is only resistant to side-channel attacks, such as timing or 798c2ecf20Sopenharmony_cielectromagnetic attacks, to the extent that the underlying Linux 808c2ecf20Sopenharmony_ciCryptographic API algorithms are. If a vulnerable algorithm is used, 818c2ecf20Sopenharmony_cisuch as a table-based implementation of AES, it may be possible for an 828c2ecf20Sopenharmony_ciattacker to mount a side channel attack against the online system. 838c2ecf20Sopenharmony_ciSide channel attacks may also be mounted against applications 848c2ecf20Sopenharmony_ciconsuming decrypted data. 858c2ecf20Sopenharmony_ci 868c2ecf20Sopenharmony_ciUnauthorized file access 878c2ecf20Sopenharmony_ci~~~~~~~~~~~~~~~~~~~~~~~~ 888c2ecf20Sopenharmony_ci 898c2ecf20Sopenharmony_ciAfter an encryption key has been added, fscrypt does not hide the 908c2ecf20Sopenharmony_ciplaintext file contents or filenames from other users on the same 918c2ecf20Sopenharmony_cisystem. Instead, existing access control mechanisms such as file mode 928c2ecf20Sopenharmony_cibits, POSIX ACLs, LSMs, or namespaces should be used for this purpose. 938c2ecf20Sopenharmony_ci 948c2ecf20Sopenharmony_ci(For the reasoning behind this, understand that while the key is 958c2ecf20Sopenharmony_ciadded, the confidentiality of the data, from the perspective of the 968c2ecf20Sopenharmony_cisystem itself, is *not* protected by the mathematical properties of 978c2ecf20Sopenharmony_ciencryption but rather only by the correctness of the kernel. 988c2ecf20Sopenharmony_ciTherefore, any encryption-specific access control checks would merely 998c2ecf20Sopenharmony_cibe enforced by kernel *code* and therefore would be largely redundant 1008c2ecf20Sopenharmony_ciwith the wide variety of access control mechanisms already available.) 1018c2ecf20Sopenharmony_ci 1028c2ecf20Sopenharmony_ciKernel memory compromise 1038c2ecf20Sopenharmony_ci~~~~~~~~~~~~~~~~~~~~~~~~ 1048c2ecf20Sopenharmony_ci 1058c2ecf20Sopenharmony_ciAn attacker who compromises the system enough to read from arbitrary 1068c2ecf20Sopenharmony_cimemory, e.g. by mounting a physical attack or by exploiting a kernel 1078c2ecf20Sopenharmony_cisecurity vulnerability, can compromise all encryption keys that are 1088c2ecf20Sopenharmony_cicurrently in use. 1098c2ecf20Sopenharmony_ci 1108c2ecf20Sopenharmony_ciHowever, fscrypt allows encryption keys to be removed from the kernel, 1118c2ecf20Sopenharmony_ciwhich may protect them from later compromise. 1128c2ecf20Sopenharmony_ci 1138c2ecf20Sopenharmony_ciIn more detail, the FS_IOC_REMOVE_ENCRYPTION_KEY ioctl (or the 1148c2ecf20Sopenharmony_ciFS_IOC_REMOVE_ENCRYPTION_KEY_ALL_USERS ioctl) can wipe a master 1158c2ecf20Sopenharmony_ciencryption key from kernel memory. If it does so, it will also try to 1168c2ecf20Sopenharmony_cievict all cached inodes which had been "unlocked" using the key, 1178c2ecf20Sopenharmony_cithereby wiping their per-file keys and making them once again appear 1188c2ecf20Sopenharmony_ci"locked", i.e. in ciphertext or encrypted form. 1198c2ecf20Sopenharmony_ci 1208c2ecf20Sopenharmony_ciHowever, these ioctls have some limitations: 1218c2ecf20Sopenharmony_ci 1228c2ecf20Sopenharmony_ci- Per-file keys for in-use files will *not* be removed or wiped. 1238c2ecf20Sopenharmony_ci Therefore, for maximum effect, userspace should close the relevant 1248c2ecf20Sopenharmony_ci encrypted files and directories before removing a master key, as 1258c2ecf20Sopenharmony_ci well as kill any processes whose working directory is in an affected 1268c2ecf20Sopenharmony_ci encrypted directory. 1278c2ecf20Sopenharmony_ci 1288c2ecf20Sopenharmony_ci- The kernel cannot magically wipe copies of the master key(s) that 1298c2ecf20Sopenharmony_ci userspace might have as well. Therefore, userspace must wipe all 1308c2ecf20Sopenharmony_ci copies of the master key(s) it makes as well; normally this should 1318c2ecf20Sopenharmony_ci be done immediately after FS_IOC_ADD_ENCRYPTION_KEY, without waiting 1328c2ecf20Sopenharmony_ci for FS_IOC_REMOVE_ENCRYPTION_KEY. Naturally, the same also applies 1338c2ecf20Sopenharmony_ci to all higher levels in the key hierarchy. Userspace should also 1348c2ecf20Sopenharmony_ci follow other security precautions such as mlock()ing memory 1358c2ecf20Sopenharmony_ci containing keys to prevent it from being swapped out. 1368c2ecf20Sopenharmony_ci 1378c2ecf20Sopenharmony_ci- In general, decrypted contents and filenames in the kernel VFS 1388c2ecf20Sopenharmony_ci caches are freed but not wiped. Therefore, portions thereof may be 1398c2ecf20Sopenharmony_ci recoverable from freed memory, even after the corresponding key(s) 1408c2ecf20Sopenharmony_ci were wiped. To partially solve this, you can set 1418c2ecf20Sopenharmony_ci CONFIG_PAGE_POISONING=y in your kernel config and add page_poison=1 1428c2ecf20Sopenharmony_ci to your kernel command line. However, this has a performance cost. 1438c2ecf20Sopenharmony_ci 1448c2ecf20Sopenharmony_ci- Secret keys might still exist in CPU registers, in crypto 1458c2ecf20Sopenharmony_ci accelerator hardware (if used by the crypto API to implement any of 1468c2ecf20Sopenharmony_ci the algorithms), or in other places not explicitly considered here. 1478c2ecf20Sopenharmony_ci 1488c2ecf20Sopenharmony_ciLimitations of v1 policies 1498c2ecf20Sopenharmony_ci~~~~~~~~~~~~~~~~~~~~~~~~~~ 1508c2ecf20Sopenharmony_ci 1518c2ecf20Sopenharmony_civ1 encryption policies have some weaknesses with respect to online 1528c2ecf20Sopenharmony_ciattacks: 1538c2ecf20Sopenharmony_ci 1548c2ecf20Sopenharmony_ci- There is no verification that the provided master key is correct. 1558c2ecf20Sopenharmony_ci Therefore, a malicious user can temporarily associate the wrong key 1568c2ecf20Sopenharmony_ci with another user's encrypted files to which they have read-only 1578c2ecf20Sopenharmony_ci access. Because of filesystem caching, the wrong key will then be 1588c2ecf20Sopenharmony_ci used by the other user's accesses to those files, even if the other 1598c2ecf20Sopenharmony_ci user has the correct key in their own keyring. This violates the 1608c2ecf20Sopenharmony_ci meaning of "read-only access". 1618c2ecf20Sopenharmony_ci 1628c2ecf20Sopenharmony_ci- A compromise of a per-file key also compromises the master key from 1638c2ecf20Sopenharmony_ci which it was derived. 1648c2ecf20Sopenharmony_ci 1658c2ecf20Sopenharmony_ci- Non-root users cannot securely remove encryption keys. 1668c2ecf20Sopenharmony_ci 1678c2ecf20Sopenharmony_ciAll the above problems are fixed with v2 encryption policies. For 1688c2ecf20Sopenharmony_cithis reason among others, it is recommended to use v2 encryption 1698c2ecf20Sopenharmony_cipolicies on all new encrypted directories. 1708c2ecf20Sopenharmony_ci 1718c2ecf20Sopenharmony_ciKey hierarchy 1728c2ecf20Sopenharmony_ci============= 1738c2ecf20Sopenharmony_ci 1748c2ecf20Sopenharmony_ciMaster Keys 1758c2ecf20Sopenharmony_ci----------- 1768c2ecf20Sopenharmony_ci 1778c2ecf20Sopenharmony_ciEach encrypted directory tree is protected by a *master key*. Master 1788c2ecf20Sopenharmony_cikeys can be up to 64 bytes long, and must be at least as long as the 1798c2ecf20Sopenharmony_cigreater of the security strength of the contents and filenames 1808c2ecf20Sopenharmony_ciencryption modes being used. For example, if any AES-256 mode is 1818c2ecf20Sopenharmony_ciused, the master key must be at least 256 bits, i.e. 32 bytes. A 1828c2ecf20Sopenharmony_cistricter requirement applies if the key is used by a v1 encryption 1838c2ecf20Sopenharmony_cipolicy and AES-256-XTS is used; such keys must be 64 bytes. 1848c2ecf20Sopenharmony_ci 1858c2ecf20Sopenharmony_ciTo "unlock" an encrypted directory tree, userspace must provide the 1868c2ecf20Sopenharmony_ciappropriate master key. There can be any number of master keys, each 1878c2ecf20Sopenharmony_ciof which protects any number of directory trees on any number of 1888c2ecf20Sopenharmony_cifilesystems. 1898c2ecf20Sopenharmony_ci 1908c2ecf20Sopenharmony_ciMaster keys must be real cryptographic keys, i.e. indistinguishable 1918c2ecf20Sopenharmony_cifrom random bytestrings of the same length. This implies that users 1928c2ecf20Sopenharmony_ci**must not** directly use a password as a master key, zero-pad a 1938c2ecf20Sopenharmony_cishorter key, or repeat a shorter key. Security cannot be guaranteed 1948c2ecf20Sopenharmony_ciif userspace makes any such error, as the cryptographic proofs and 1958c2ecf20Sopenharmony_cianalysis would no longer apply. 1968c2ecf20Sopenharmony_ci 1978c2ecf20Sopenharmony_ciInstead, users should generate master keys either using a 1988c2ecf20Sopenharmony_cicryptographically secure random number generator, or by using a KDF 1998c2ecf20Sopenharmony_ci(Key Derivation Function). The kernel does not do any key stretching; 2008c2ecf20Sopenharmony_citherefore, if userspace derives the key from a low-entropy secret such 2018c2ecf20Sopenharmony_cias a passphrase, it is critical that a KDF designed for this purpose 2028c2ecf20Sopenharmony_cibe used, such as scrypt, PBKDF2, or Argon2. 2038c2ecf20Sopenharmony_ci 2048c2ecf20Sopenharmony_ciKey derivation function 2058c2ecf20Sopenharmony_ci----------------------- 2068c2ecf20Sopenharmony_ci 2078c2ecf20Sopenharmony_ciWith one exception, fscrypt never uses the master key(s) for 2088c2ecf20Sopenharmony_ciencryption directly. Instead, they are only used as input to a KDF 2098c2ecf20Sopenharmony_ci(Key Derivation Function) to derive the actual keys. 2108c2ecf20Sopenharmony_ci 2118c2ecf20Sopenharmony_ciThe KDF used for a particular master key differs depending on whether 2128c2ecf20Sopenharmony_cithe key is used for v1 encryption policies or for v2 encryption 2138c2ecf20Sopenharmony_cipolicies. Users **must not** use the same key for both v1 and v2 2148c2ecf20Sopenharmony_ciencryption policies. (No real-world attack is currently known on this 2158c2ecf20Sopenharmony_cispecific case of key reuse, but its security cannot be guaranteed 2168c2ecf20Sopenharmony_cisince the cryptographic proofs and analysis would no longer apply.) 2178c2ecf20Sopenharmony_ci 2188c2ecf20Sopenharmony_ciFor v1 encryption policies, the KDF only supports deriving per-file 2198c2ecf20Sopenharmony_ciencryption keys. It works by encrypting the master key with 2208c2ecf20Sopenharmony_ciAES-128-ECB, using the file's 16-byte nonce as the AES key. The 2218c2ecf20Sopenharmony_ciresulting ciphertext is used as the derived key. If the ciphertext is 2228c2ecf20Sopenharmony_cilonger than needed, then it is truncated to the needed length. 2238c2ecf20Sopenharmony_ci 2248c2ecf20Sopenharmony_ciFor v2 encryption policies, the KDF is HKDF-SHA512. The master key is 2258c2ecf20Sopenharmony_cipassed as the "input keying material", no salt is used, and a distinct 2268c2ecf20Sopenharmony_ci"application-specific information string" is used for each distinct 2278c2ecf20Sopenharmony_cikey to be derived. For example, when a per-file encryption key is 2288c2ecf20Sopenharmony_ciderived, the application-specific information string is the file's 2298c2ecf20Sopenharmony_cinonce prefixed with "fscrypt\\0" and a context byte. Different 2308c2ecf20Sopenharmony_cicontext bytes are used for other types of derived keys. 2318c2ecf20Sopenharmony_ci 2328c2ecf20Sopenharmony_ciHKDF-SHA512 is preferred to the original AES-128-ECB based KDF because 2338c2ecf20Sopenharmony_ciHKDF is more flexible, is nonreversible, and evenly distributes 2348c2ecf20Sopenharmony_cientropy from the master key. HKDF is also standardized and widely 2358c2ecf20Sopenharmony_ciused by other software, whereas the AES-128-ECB based KDF is ad-hoc. 2368c2ecf20Sopenharmony_ci 2378c2ecf20Sopenharmony_ciPer-file encryption keys 2388c2ecf20Sopenharmony_ci------------------------ 2398c2ecf20Sopenharmony_ci 2408c2ecf20Sopenharmony_ciSince each master key can protect many files, it is necessary to 2418c2ecf20Sopenharmony_ci"tweak" the encryption of each file so that the same plaintext in two 2428c2ecf20Sopenharmony_cifiles doesn't map to the same ciphertext, or vice versa. In most 2438c2ecf20Sopenharmony_cicases, fscrypt does this by deriving per-file keys. When a new 2448c2ecf20Sopenharmony_ciencrypted inode (regular file, directory, or symlink) is created, 2458c2ecf20Sopenharmony_cifscrypt randomly generates a 16-byte nonce and stores it in the 2468c2ecf20Sopenharmony_ciinode's encryption xattr. Then, it uses a KDF (as described in `Key 2478c2ecf20Sopenharmony_ciderivation function`_) to derive the file's key from the master key 2488c2ecf20Sopenharmony_ciand nonce. 2498c2ecf20Sopenharmony_ci 2508c2ecf20Sopenharmony_ciKey derivation was chosen over key wrapping because wrapped keys would 2518c2ecf20Sopenharmony_cirequire larger xattrs which would be less likely to fit in-line in the 2528c2ecf20Sopenharmony_cifilesystem's inode table, and there didn't appear to be any 2538c2ecf20Sopenharmony_cisignificant advantages to key wrapping. In particular, currently 2548c2ecf20Sopenharmony_cithere is no requirement to support unlocking a file with multiple 2558c2ecf20Sopenharmony_cialternative master keys or to support rotating master keys. Instead, 2568c2ecf20Sopenharmony_cithe master keys may be wrapped in userspace, e.g. as is done by the 2578c2ecf20Sopenharmony_ci`fscrypt <https://github.com/google/fscrypt>`_ tool. 2588c2ecf20Sopenharmony_ci 2598c2ecf20Sopenharmony_ciDIRECT_KEY policies 2608c2ecf20Sopenharmony_ci------------------- 2618c2ecf20Sopenharmony_ci 2628c2ecf20Sopenharmony_ciThe Adiantum encryption mode (see `Encryption modes and usage`_) is 2638c2ecf20Sopenharmony_cisuitable for both contents and filenames encryption, and it accepts 2648c2ecf20Sopenharmony_cilong IVs --- long enough to hold both an 8-byte logical block number 2658c2ecf20Sopenharmony_ciand a 16-byte per-file nonce. Also, the overhead of each Adiantum key 2668c2ecf20Sopenharmony_ciis greater than that of an AES-256-XTS key. 2678c2ecf20Sopenharmony_ci 2688c2ecf20Sopenharmony_ciTherefore, to improve performance and save memory, for Adiantum a 2698c2ecf20Sopenharmony_ci"direct key" configuration is supported. When the user has enabled 2708c2ecf20Sopenharmony_cithis by setting FSCRYPT_POLICY_FLAG_DIRECT_KEY in the fscrypt policy, 2718c2ecf20Sopenharmony_ciper-file encryption keys are not used. Instead, whenever any data 2728c2ecf20Sopenharmony_ci(contents or filenames) is encrypted, the file's 16-byte nonce is 2738c2ecf20Sopenharmony_ciincluded in the IV. Moreover: 2748c2ecf20Sopenharmony_ci 2758c2ecf20Sopenharmony_ci- For v1 encryption policies, the encryption is done directly with the 2768c2ecf20Sopenharmony_ci master key. Because of this, users **must not** use the same master 2778c2ecf20Sopenharmony_ci key for any other purpose, even for other v1 policies. 2788c2ecf20Sopenharmony_ci 2798c2ecf20Sopenharmony_ci- For v2 encryption policies, the encryption is done with a per-mode 2808c2ecf20Sopenharmony_ci key derived using the KDF. Users may use the same master key for 2818c2ecf20Sopenharmony_ci other v2 encryption policies. 2828c2ecf20Sopenharmony_ci 2838c2ecf20Sopenharmony_ciIV_INO_LBLK_64 policies 2848c2ecf20Sopenharmony_ci----------------------- 2858c2ecf20Sopenharmony_ci 2868c2ecf20Sopenharmony_ciWhen FSCRYPT_POLICY_FLAG_IV_INO_LBLK_64 is set in the fscrypt policy, 2878c2ecf20Sopenharmony_cithe encryption keys are derived from the master key, encryption mode 2888c2ecf20Sopenharmony_cinumber, and filesystem UUID. This normally results in all files 2898c2ecf20Sopenharmony_ciprotected by the same master key sharing a single contents encryption 2908c2ecf20Sopenharmony_cikey and a single filenames encryption key. To still encrypt different 2918c2ecf20Sopenharmony_cifiles' data differently, inode numbers are included in the IVs. 2928c2ecf20Sopenharmony_ciConsequently, shrinking the filesystem may not be allowed. 2938c2ecf20Sopenharmony_ci 2948c2ecf20Sopenharmony_ciThis format is optimized for use with inline encryption hardware 2958c2ecf20Sopenharmony_cicompliant with the UFS standard, which supports only 64 IV bits per 2968c2ecf20Sopenharmony_ciI/O request and may have only a small number of keyslots. 2978c2ecf20Sopenharmony_ci 2988c2ecf20Sopenharmony_ciIV_INO_LBLK_32 policies 2998c2ecf20Sopenharmony_ci----------------------- 3008c2ecf20Sopenharmony_ci 3018c2ecf20Sopenharmony_ciIV_INO_LBLK_32 policies work like IV_INO_LBLK_64, except that for 3028c2ecf20Sopenharmony_ciIV_INO_LBLK_32, the inode number is hashed with SipHash-2-4 (where the 3038c2ecf20Sopenharmony_ciSipHash key is derived from the master key) and added to the file 3048c2ecf20Sopenharmony_cilogical block number mod 2^32 to produce a 32-bit IV. 3058c2ecf20Sopenharmony_ci 3068c2ecf20Sopenharmony_ciThis format is optimized for use with inline encryption hardware 3078c2ecf20Sopenharmony_cicompliant with the eMMC v5.2 standard, which supports only 32 IV bits 3088c2ecf20Sopenharmony_ciper I/O request and may have only a small number of keyslots. This 3098c2ecf20Sopenharmony_ciformat results in some level of IV reuse, so it should only be used 3108c2ecf20Sopenharmony_ciwhen necessary due to hardware limitations. 3118c2ecf20Sopenharmony_ci 3128c2ecf20Sopenharmony_ciKey identifiers 3138c2ecf20Sopenharmony_ci--------------- 3148c2ecf20Sopenharmony_ci 3158c2ecf20Sopenharmony_ciFor master keys used for v2 encryption policies, a unique 16-byte "key 3168c2ecf20Sopenharmony_ciidentifier" is also derived using the KDF. This value is stored in 3178c2ecf20Sopenharmony_cithe clear, since it is needed to reliably identify the key itself. 3188c2ecf20Sopenharmony_ci 3198c2ecf20Sopenharmony_ciDirhash keys 3208c2ecf20Sopenharmony_ci------------ 3218c2ecf20Sopenharmony_ci 3228c2ecf20Sopenharmony_ciFor directories that are indexed using a secret-keyed dirhash over the 3238c2ecf20Sopenharmony_ciplaintext filenames, the KDF is also used to derive a 128-bit 3248c2ecf20Sopenharmony_ciSipHash-2-4 key per directory in order to hash filenames. This works 3258c2ecf20Sopenharmony_cijust like deriving a per-file encryption key, except that a different 3268c2ecf20Sopenharmony_ciKDF context is used. Currently, only casefolded ("case-insensitive") 3278c2ecf20Sopenharmony_ciencrypted directories use this style of hashing. 3288c2ecf20Sopenharmony_ci 3298c2ecf20Sopenharmony_ciEncryption modes and usage 3308c2ecf20Sopenharmony_ci========================== 3318c2ecf20Sopenharmony_ci 3328c2ecf20Sopenharmony_cifscrypt allows one encryption mode to be specified for file contents 3338c2ecf20Sopenharmony_ciand one encryption mode to be specified for filenames. Different 3348c2ecf20Sopenharmony_cidirectory trees are permitted to use different encryption modes. 3358c2ecf20Sopenharmony_ciCurrently, the following pairs of encryption modes are supported: 3368c2ecf20Sopenharmony_ci 3378c2ecf20Sopenharmony_ci- AES-256-XTS for contents and AES-256-CTS-CBC for filenames 3388c2ecf20Sopenharmony_ci- AES-128-CBC for contents and AES-128-CTS-CBC for filenames 3398c2ecf20Sopenharmony_ci- Adiantum for both contents and filenames 3408c2ecf20Sopenharmony_ci 3418c2ecf20Sopenharmony_ciIf unsure, you should use the (AES-256-XTS, AES-256-CTS-CBC) pair. 3428c2ecf20Sopenharmony_ci 3438c2ecf20Sopenharmony_ciAES-128-CBC was added only for low-powered embedded devices with 3448c2ecf20Sopenharmony_cicrypto accelerators such as CAAM or CESA that do not support XTS. To 3458c2ecf20Sopenharmony_ciuse AES-128-CBC, CONFIG_CRYPTO_ESSIV and CONFIG_CRYPTO_SHA256 (or 3468c2ecf20Sopenharmony_cianother SHA-256 implementation) must be enabled so that ESSIV can be 3478c2ecf20Sopenharmony_ciused. 3488c2ecf20Sopenharmony_ci 3498c2ecf20Sopenharmony_ciAdiantum is a (primarily) stream cipher-based mode that is fast even 3508c2ecf20Sopenharmony_cion CPUs without dedicated crypto instructions. It's also a true 3518c2ecf20Sopenharmony_ciwide-block mode, unlike XTS. It can also eliminate the need to derive 3528c2ecf20Sopenharmony_ciper-file encryption keys. However, it depends on the security of two 3538c2ecf20Sopenharmony_ciprimitives, XChaCha12 and AES-256, rather than just one. See the 3548c2ecf20Sopenharmony_cipaper "Adiantum: length-preserving encryption for entry-level 3558c2ecf20Sopenharmony_ciprocessors" (https://eprint.iacr.org/2018/720.pdf) for more details. 3568c2ecf20Sopenharmony_ciTo use Adiantum, CONFIG_CRYPTO_ADIANTUM must be enabled. Also, fast 3578c2ecf20Sopenharmony_ciimplementations of ChaCha and NHPoly1305 should be enabled, e.g. 3588c2ecf20Sopenharmony_ciCONFIG_CRYPTO_CHACHA20_NEON and CONFIG_CRYPTO_NHPOLY1305_NEON for ARM. 3598c2ecf20Sopenharmony_ci 3608c2ecf20Sopenharmony_ciNew encryption modes can be added relatively easily, without changes 3618c2ecf20Sopenharmony_cito individual filesystems. However, authenticated encryption (AE) 3628c2ecf20Sopenharmony_cimodes are not currently supported because of the difficulty of dealing 3638c2ecf20Sopenharmony_ciwith ciphertext expansion. 3648c2ecf20Sopenharmony_ci 3658c2ecf20Sopenharmony_ciContents encryption 3668c2ecf20Sopenharmony_ci------------------- 3678c2ecf20Sopenharmony_ci 3688c2ecf20Sopenharmony_ciFor file contents, each filesystem block is encrypted independently. 3698c2ecf20Sopenharmony_ciStarting from Linux kernel 5.5, encryption of filesystems with block 3708c2ecf20Sopenharmony_cisize less than system's page size is supported. 3718c2ecf20Sopenharmony_ci 3728c2ecf20Sopenharmony_ciEach block's IV is set to the logical block number within the file as 3738c2ecf20Sopenharmony_cia little endian number, except that: 3748c2ecf20Sopenharmony_ci 3758c2ecf20Sopenharmony_ci- With CBC mode encryption, ESSIV is also used. Specifically, each IV 3768c2ecf20Sopenharmony_ci is encrypted with AES-256 where the AES-256 key is the SHA-256 hash 3778c2ecf20Sopenharmony_ci of the file's data encryption key. 3788c2ecf20Sopenharmony_ci 3798c2ecf20Sopenharmony_ci- With `DIRECT_KEY policies`_, the file's nonce is appended to the IV. 3808c2ecf20Sopenharmony_ci Currently this is only allowed with the Adiantum encryption mode. 3818c2ecf20Sopenharmony_ci 3828c2ecf20Sopenharmony_ci- With `IV_INO_LBLK_64 policies`_, the logical block number is limited 3838c2ecf20Sopenharmony_ci to 32 bits and is placed in bits 0-31 of the IV. The inode number 3848c2ecf20Sopenharmony_ci (which is also limited to 32 bits) is placed in bits 32-63. 3858c2ecf20Sopenharmony_ci 3868c2ecf20Sopenharmony_ci- With `IV_INO_LBLK_32 policies`_, the logical block number is limited 3878c2ecf20Sopenharmony_ci to 32 bits and is placed in bits 0-31 of the IV. The inode number 3888c2ecf20Sopenharmony_ci is then hashed and added mod 2^32. 3898c2ecf20Sopenharmony_ci 3908c2ecf20Sopenharmony_ciNote that because file logical block numbers are included in the IVs, 3918c2ecf20Sopenharmony_cifilesystems must enforce that blocks are never shifted around within 3928c2ecf20Sopenharmony_ciencrypted files, e.g. via "collapse range" or "insert range". 3938c2ecf20Sopenharmony_ci 3948c2ecf20Sopenharmony_ciFilenames encryption 3958c2ecf20Sopenharmony_ci-------------------- 3968c2ecf20Sopenharmony_ci 3978c2ecf20Sopenharmony_ciFor filenames, each full filename is encrypted at once. Because of 3988c2ecf20Sopenharmony_cithe requirements to retain support for efficient directory lookups and 3998c2ecf20Sopenharmony_cifilenames of up to 255 bytes, the same IV is used for every filename 4008c2ecf20Sopenharmony_ciin a directory. 4018c2ecf20Sopenharmony_ci 4028c2ecf20Sopenharmony_ciHowever, each encrypted directory still uses a unique key, or 4038c2ecf20Sopenharmony_cialternatively has the file's nonce (for `DIRECT_KEY policies`_) or 4048c2ecf20Sopenharmony_ciinode number (for `IV_INO_LBLK_64 policies`_) included in the IVs. 4058c2ecf20Sopenharmony_ciThus, IV reuse is limited to within a single directory. 4068c2ecf20Sopenharmony_ci 4078c2ecf20Sopenharmony_ciWith CTS-CBC, the IV reuse means that when the plaintext filenames 4088c2ecf20Sopenharmony_cishare a common prefix at least as long as the cipher block size (16 4098c2ecf20Sopenharmony_cibytes for AES), the corresponding encrypted filenames will also share 4108c2ecf20Sopenharmony_cia common prefix. This is undesirable. Adiantum does not have this 4118c2ecf20Sopenharmony_ciweakness, as it is a wide-block encryption mode. 4128c2ecf20Sopenharmony_ci 4138c2ecf20Sopenharmony_ciAll supported filenames encryption modes accept any plaintext length 4148c2ecf20Sopenharmony_ci>= 16 bytes; cipher block alignment is not required. However, 4158c2ecf20Sopenharmony_cifilenames shorter than 16 bytes are NUL-padded to 16 bytes before 4168c2ecf20Sopenharmony_cibeing encrypted. In addition, to reduce leakage of filename lengths 4178c2ecf20Sopenharmony_civia their ciphertexts, all filenames are NUL-padded to the next 4, 8, 4188c2ecf20Sopenharmony_ci16, or 32-byte boundary (configurable). 32 is recommended since this 4198c2ecf20Sopenharmony_ciprovides the best confidentiality, at the cost of making directory 4208c2ecf20Sopenharmony_cientries consume slightly more space. Note that since NUL (``\0``) is 4218c2ecf20Sopenharmony_cinot otherwise a valid character in filenames, the padding will never 4228c2ecf20Sopenharmony_ciproduce duplicate plaintexts. 4238c2ecf20Sopenharmony_ci 4248c2ecf20Sopenharmony_ciSymbolic link targets are considered a type of filename and are 4258c2ecf20Sopenharmony_ciencrypted in the same way as filenames in directory entries, except 4268c2ecf20Sopenharmony_cithat IV reuse is not a problem as each symlink has its own inode. 4278c2ecf20Sopenharmony_ci 4288c2ecf20Sopenharmony_ciUser API 4298c2ecf20Sopenharmony_ci======== 4308c2ecf20Sopenharmony_ci 4318c2ecf20Sopenharmony_ciSetting an encryption policy 4328c2ecf20Sopenharmony_ci---------------------------- 4338c2ecf20Sopenharmony_ci 4348c2ecf20Sopenharmony_ciFS_IOC_SET_ENCRYPTION_POLICY 4358c2ecf20Sopenharmony_ci~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 4368c2ecf20Sopenharmony_ci 4378c2ecf20Sopenharmony_ciThe FS_IOC_SET_ENCRYPTION_POLICY ioctl sets an encryption policy on an 4388c2ecf20Sopenharmony_ciempty directory or verifies that a directory or regular file already 4398c2ecf20Sopenharmony_cihas the specified encryption policy. It takes in a pointer to 4408c2ecf20Sopenharmony_cistruct fscrypt_policy_v1 or struct fscrypt_policy_v2, defined as 4418c2ecf20Sopenharmony_cifollows:: 4428c2ecf20Sopenharmony_ci 4438c2ecf20Sopenharmony_ci #define FSCRYPT_POLICY_V1 0 4448c2ecf20Sopenharmony_ci #define FSCRYPT_KEY_DESCRIPTOR_SIZE 8 4458c2ecf20Sopenharmony_ci struct fscrypt_policy_v1 { 4468c2ecf20Sopenharmony_ci __u8 version; 4478c2ecf20Sopenharmony_ci __u8 contents_encryption_mode; 4488c2ecf20Sopenharmony_ci __u8 filenames_encryption_mode; 4498c2ecf20Sopenharmony_ci __u8 flags; 4508c2ecf20Sopenharmony_ci __u8 master_key_descriptor[FSCRYPT_KEY_DESCRIPTOR_SIZE]; 4518c2ecf20Sopenharmony_ci }; 4528c2ecf20Sopenharmony_ci #define fscrypt_policy fscrypt_policy_v1 4538c2ecf20Sopenharmony_ci 4548c2ecf20Sopenharmony_ci #define FSCRYPT_POLICY_V2 2 4558c2ecf20Sopenharmony_ci #define FSCRYPT_KEY_IDENTIFIER_SIZE 16 4568c2ecf20Sopenharmony_ci struct fscrypt_policy_v2 { 4578c2ecf20Sopenharmony_ci __u8 version; 4588c2ecf20Sopenharmony_ci __u8 contents_encryption_mode; 4598c2ecf20Sopenharmony_ci __u8 filenames_encryption_mode; 4608c2ecf20Sopenharmony_ci __u8 flags; 4618c2ecf20Sopenharmony_ci __u8 __reserved[4]; 4628c2ecf20Sopenharmony_ci __u8 master_key_identifier[FSCRYPT_KEY_IDENTIFIER_SIZE]; 4638c2ecf20Sopenharmony_ci }; 4648c2ecf20Sopenharmony_ci 4658c2ecf20Sopenharmony_ciThis structure must be initialized as follows: 4668c2ecf20Sopenharmony_ci 4678c2ecf20Sopenharmony_ci- ``version`` must be FSCRYPT_POLICY_V1 (0) if 4688c2ecf20Sopenharmony_ci struct fscrypt_policy_v1 is used or FSCRYPT_POLICY_V2 (2) if 4698c2ecf20Sopenharmony_ci struct fscrypt_policy_v2 is used. (Note: we refer to the original 4708c2ecf20Sopenharmony_ci policy version as "v1", though its version code is really 0.) 4718c2ecf20Sopenharmony_ci For new encrypted directories, use v2 policies. 4728c2ecf20Sopenharmony_ci 4738c2ecf20Sopenharmony_ci- ``contents_encryption_mode`` and ``filenames_encryption_mode`` must 4748c2ecf20Sopenharmony_ci be set to constants from ``<linux/fscrypt.h>`` which identify the 4758c2ecf20Sopenharmony_ci encryption modes to use. If unsure, use FSCRYPT_MODE_AES_256_XTS 4768c2ecf20Sopenharmony_ci (1) for ``contents_encryption_mode`` and FSCRYPT_MODE_AES_256_CTS 4778c2ecf20Sopenharmony_ci (4) for ``filenames_encryption_mode``. 4788c2ecf20Sopenharmony_ci 4798c2ecf20Sopenharmony_ci- ``flags`` contains optional flags from ``<linux/fscrypt.h>``: 4808c2ecf20Sopenharmony_ci 4818c2ecf20Sopenharmony_ci - FSCRYPT_POLICY_FLAGS_PAD_*: The amount of NUL padding to use when 4828c2ecf20Sopenharmony_ci encrypting filenames. If unsure, use FSCRYPT_POLICY_FLAGS_PAD_32 4838c2ecf20Sopenharmony_ci (0x3). 4848c2ecf20Sopenharmony_ci - FSCRYPT_POLICY_FLAG_DIRECT_KEY: See `DIRECT_KEY policies`_. 4858c2ecf20Sopenharmony_ci - FSCRYPT_POLICY_FLAG_IV_INO_LBLK_64: See `IV_INO_LBLK_64 4868c2ecf20Sopenharmony_ci policies`_. 4878c2ecf20Sopenharmony_ci - FSCRYPT_POLICY_FLAG_IV_INO_LBLK_32: See `IV_INO_LBLK_32 4888c2ecf20Sopenharmony_ci policies`_. 4898c2ecf20Sopenharmony_ci 4908c2ecf20Sopenharmony_ci v1 encryption policies only support the PAD_* and DIRECT_KEY flags. 4918c2ecf20Sopenharmony_ci The other flags are only supported by v2 encryption policies. 4928c2ecf20Sopenharmony_ci 4938c2ecf20Sopenharmony_ci The DIRECT_KEY, IV_INO_LBLK_64, and IV_INO_LBLK_32 flags are 4948c2ecf20Sopenharmony_ci mutually exclusive. 4958c2ecf20Sopenharmony_ci 4968c2ecf20Sopenharmony_ci- For v2 encryption policies, ``__reserved`` must be zeroed. 4978c2ecf20Sopenharmony_ci 4988c2ecf20Sopenharmony_ci- For v1 encryption policies, ``master_key_descriptor`` specifies how 4998c2ecf20Sopenharmony_ci to find the master key in a keyring; see `Adding keys`_. It is up 5008c2ecf20Sopenharmony_ci to userspace to choose a unique ``master_key_descriptor`` for each 5018c2ecf20Sopenharmony_ci master key. The e4crypt and fscrypt tools use the first 8 bytes of 5028c2ecf20Sopenharmony_ci ``SHA-512(SHA-512(master_key))``, but this particular scheme is not 5038c2ecf20Sopenharmony_ci required. Also, the master key need not be in the keyring yet when 5048c2ecf20Sopenharmony_ci FS_IOC_SET_ENCRYPTION_POLICY is executed. However, it must be added 5058c2ecf20Sopenharmony_ci before any files can be created in the encrypted directory. 5068c2ecf20Sopenharmony_ci 5078c2ecf20Sopenharmony_ci For v2 encryption policies, ``master_key_descriptor`` has been 5088c2ecf20Sopenharmony_ci replaced with ``master_key_identifier``, which is longer and cannot 5098c2ecf20Sopenharmony_ci be arbitrarily chosen. Instead, the key must first be added using 5108c2ecf20Sopenharmony_ci `FS_IOC_ADD_ENCRYPTION_KEY`_. Then, the ``key_spec.u.identifier`` 5118c2ecf20Sopenharmony_ci the kernel returned in the struct fscrypt_add_key_arg must 5128c2ecf20Sopenharmony_ci be used as the ``master_key_identifier`` in 5138c2ecf20Sopenharmony_ci struct fscrypt_policy_v2. 5148c2ecf20Sopenharmony_ci 5158c2ecf20Sopenharmony_ciIf the file is not yet encrypted, then FS_IOC_SET_ENCRYPTION_POLICY 5168c2ecf20Sopenharmony_civerifies that the file is an empty directory. If so, the specified 5178c2ecf20Sopenharmony_ciencryption policy is assigned to the directory, turning it into an 5188c2ecf20Sopenharmony_ciencrypted directory. After that, and after providing the 5198c2ecf20Sopenharmony_cicorresponding master key as described in `Adding keys`_, all regular 5208c2ecf20Sopenharmony_cifiles, directories (recursively), and symlinks created in the 5218c2ecf20Sopenharmony_cidirectory will be encrypted, inheriting the same encryption policy. 5228c2ecf20Sopenharmony_ciThe filenames in the directory's entries will be encrypted as well. 5238c2ecf20Sopenharmony_ci 5248c2ecf20Sopenharmony_ciAlternatively, if the file is already encrypted, then 5258c2ecf20Sopenharmony_ciFS_IOC_SET_ENCRYPTION_POLICY validates that the specified encryption 5268c2ecf20Sopenharmony_cipolicy exactly matches the actual one. If they match, then the ioctl 5278c2ecf20Sopenharmony_cireturns 0. Otherwise, it fails with EEXIST. This works on both 5288c2ecf20Sopenharmony_ciregular files and directories, including nonempty directories. 5298c2ecf20Sopenharmony_ci 5308c2ecf20Sopenharmony_ciWhen a v2 encryption policy is assigned to a directory, it is also 5318c2ecf20Sopenharmony_cirequired that either the specified key has been added by the current 5328c2ecf20Sopenharmony_ciuser or that the caller has CAP_FOWNER in the initial user namespace. 5338c2ecf20Sopenharmony_ci(This is needed to prevent a user from encrypting their data with 5348c2ecf20Sopenharmony_cianother user's key.) The key must remain added while 5358c2ecf20Sopenharmony_ciFS_IOC_SET_ENCRYPTION_POLICY is executing. However, if the new 5368c2ecf20Sopenharmony_ciencrypted directory does not need to be accessed immediately, then the 5378c2ecf20Sopenharmony_cikey can be removed right away afterwards. 5388c2ecf20Sopenharmony_ci 5398c2ecf20Sopenharmony_ciNote that the ext4 filesystem does not allow the root directory to be 5408c2ecf20Sopenharmony_ciencrypted, even if it is empty. Users who want to encrypt an entire 5418c2ecf20Sopenharmony_cifilesystem with one key should consider using dm-crypt instead. 5428c2ecf20Sopenharmony_ci 5438c2ecf20Sopenharmony_ciFS_IOC_SET_ENCRYPTION_POLICY can fail with the following errors: 5448c2ecf20Sopenharmony_ci 5458c2ecf20Sopenharmony_ci- ``EACCES``: the file is not owned by the process's uid, nor does the 5468c2ecf20Sopenharmony_ci process have the CAP_FOWNER capability in a namespace with the file 5478c2ecf20Sopenharmony_ci owner's uid mapped 5488c2ecf20Sopenharmony_ci- ``EEXIST``: the file is already encrypted with an encryption policy 5498c2ecf20Sopenharmony_ci different from the one specified 5508c2ecf20Sopenharmony_ci- ``EINVAL``: an invalid encryption policy was specified (invalid 5518c2ecf20Sopenharmony_ci version, mode(s), or flags; or reserved bits were set); or a v1 5528c2ecf20Sopenharmony_ci encryption policy was specified but the directory has the casefold 5538c2ecf20Sopenharmony_ci flag enabled (casefolding is incompatible with v1 policies). 5548c2ecf20Sopenharmony_ci- ``ENOKEY``: a v2 encryption policy was specified, but the key with 5558c2ecf20Sopenharmony_ci the specified ``master_key_identifier`` has not been added, nor does 5568c2ecf20Sopenharmony_ci the process have the CAP_FOWNER capability in the initial user 5578c2ecf20Sopenharmony_ci namespace 5588c2ecf20Sopenharmony_ci- ``ENOTDIR``: the file is unencrypted and is a regular file, not a 5598c2ecf20Sopenharmony_ci directory 5608c2ecf20Sopenharmony_ci- ``ENOTEMPTY``: the file is unencrypted and is a nonempty directory 5618c2ecf20Sopenharmony_ci- ``ENOTTY``: this type of filesystem does not implement encryption 5628c2ecf20Sopenharmony_ci- ``EOPNOTSUPP``: the kernel was not configured with encryption 5638c2ecf20Sopenharmony_ci support for filesystems, or the filesystem superblock has not 5648c2ecf20Sopenharmony_ci had encryption enabled on it. (For example, to use encryption on an 5658c2ecf20Sopenharmony_ci ext4 filesystem, CONFIG_FS_ENCRYPTION must be enabled in the 5668c2ecf20Sopenharmony_ci kernel config, and the superblock must have had the "encrypt" 5678c2ecf20Sopenharmony_ci feature flag enabled using ``tune2fs -O encrypt`` or ``mkfs.ext4 -O 5688c2ecf20Sopenharmony_ci encrypt``.) 5698c2ecf20Sopenharmony_ci- ``EPERM``: this directory may not be encrypted, e.g. because it is 5708c2ecf20Sopenharmony_ci the root directory of an ext4 filesystem 5718c2ecf20Sopenharmony_ci- ``EROFS``: the filesystem is readonly 5728c2ecf20Sopenharmony_ci 5738c2ecf20Sopenharmony_ciGetting an encryption policy 5748c2ecf20Sopenharmony_ci---------------------------- 5758c2ecf20Sopenharmony_ci 5768c2ecf20Sopenharmony_ciTwo ioctls are available to get a file's encryption policy: 5778c2ecf20Sopenharmony_ci 5788c2ecf20Sopenharmony_ci- `FS_IOC_GET_ENCRYPTION_POLICY_EX`_ 5798c2ecf20Sopenharmony_ci- `FS_IOC_GET_ENCRYPTION_POLICY`_ 5808c2ecf20Sopenharmony_ci 5818c2ecf20Sopenharmony_ciThe extended (_EX) version of the ioctl is more general and is 5828c2ecf20Sopenharmony_cirecommended to use when possible. However, on older kernels only the 5838c2ecf20Sopenharmony_cioriginal ioctl is available. Applications should try the extended 5848c2ecf20Sopenharmony_civersion, and if it fails with ENOTTY fall back to the original 5858c2ecf20Sopenharmony_civersion. 5868c2ecf20Sopenharmony_ci 5878c2ecf20Sopenharmony_ciFS_IOC_GET_ENCRYPTION_POLICY_EX 5888c2ecf20Sopenharmony_ci~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 5898c2ecf20Sopenharmony_ci 5908c2ecf20Sopenharmony_ciThe FS_IOC_GET_ENCRYPTION_POLICY_EX ioctl retrieves the encryption 5918c2ecf20Sopenharmony_cipolicy, if any, for a directory or regular file. No additional 5928c2ecf20Sopenharmony_cipermissions are required beyond the ability to open the file. It 5938c2ecf20Sopenharmony_citakes in a pointer to struct fscrypt_get_policy_ex_arg, 5948c2ecf20Sopenharmony_cidefined as follows:: 5958c2ecf20Sopenharmony_ci 5968c2ecf20Sopenharmony_ci struct fscrypt_get_policy_ex_arg { 5978c2ecf20Sopenharmony_ci __u64 policy_size; /* input/output */ 5988c2ecf20Sopenharmony_ci union { 5998c2ecf20Sopenharmony_ci __u8 version; 6008c2ecf20Sopenharmony_ci struct fscrypt_policy_v1 v1; 6018c2ecf20Sopenharmony_ci struct fscrypt_policy_v2 v2; 6028c2ecf20Sopenharmony_ci } policy; /* output */ 6038c2ecf20Sopenharmony_ci }; 6048c2ecf20Sopenharmony_ci 6058c2ecf20Sopenharmony_ciThe caller must initialize ``policy_size`` to the size available for 6068c2ecf20Sopenharmony_cithe policy struct, i.e. ``sizeof(arg.policy)``. 6078c2ecf20Sopenharmony_ci 6088c2ecf20Sopenharmony_ciOn success, the policy struct is returned in ``policy``, and its 6098c2ecf20Sopenharmony_ciactual size is returned in ``policy_size``. ``policy.version`` should 6108c2ecf20Sopenharmony_cibe checked to determine the version of policy returned. Note that the 6118c2ecf20Sopenharmony_civersion code for the "v1" policy is actually 0 (FSCRYPT_POLICY_V1). 6128c2ecf20Sopenharmony_ci 6138c2ecf20Sopenharmony_ciFS_IOC_GET_ENCRYPTION_POLICY_EX can fail with the following errors: 6148c2ecf20Sopenharmony_ci 6158c2ecf20Sopenharmony_ci- ``EINVAL``: the file is encrypted, but it uses an unrecognized 6168c2ecf20Sopenharmony_ci encryption policy version 6178c2ecf20Sopenharmony_ci- ``ENODATA``: the file is not encrypted 6188c2ecf20Sopenharmony_ci- ``ENOTTY``: this type of filesystem does not implement encryption, 6198c2ecf20Sopenharmony_ci or this kernel is too old to support FS_IOC_GET_ENCRYPTION_POLICY_EX 6208c2ecf20Sopenharmony_ci (try FS_IOC_GET_ENCRYPTION_POLICY instead) 6218c2ecf20Sopenharmony_ci- ``EOPNOTSUPP``: the kernel was not configured with encryption 6228c2ecf20Sopenharmony_ci support for this filesystem, or the filesystem superblock has not 6238c2ecf20Sopenharmony_ci had encryption enabled on it 6248c2ecf20Sopenharmony_ci- ``EOVERFLOW``: the file is encrypted and uses a recognized 6258c2ecf20Sopenharmony_ci encryption policy version, but the policy struct does not fit into 6268c2ecf20Sopenharmony_ci the provided buffer 6278c2ecf20Sopenharmony_ci 6288c2ecf20Sopenharmony_ciNote: if you only need to know whether a file is encrypted or not, on 6298c2ecf20Sopenharmony_cimost filesystems it is also possible to use the FS_IOC_GETFLAGS ioctl 6308c2ecf20Sopenharmony_ciand check for FS_ENCRYPT_FL, or to use the statx() system call and 6318c2ecf20Sopenharmony_cicheck for STATX_ATTR_ENCRYPTED in stx_attributes. 6328c2ecf20Sopenharmony_ci 6338c2ecf20Sopenharmony_ciFS_IOC_GET_ENCRYPTION_POLICY 6348c2ecf20Sopenharmony_ci~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 6358c2ecf20Sopenharmony_ci 6368c2ecf20Sopenharmony_ciThe FS_IOC_GET_ENCRYPTION_POLICY ioctl can also retrieve the 6378c2ecf20Sopenharmony_ciencryption policy, if any, for a directory or regular file. However, 6388c2ecf20Sopenharmony_ciunlike `FS_IOC_GET_ENCRYPTION_POLICY_EX`_, 6398c2ecf20Sopenharmony_ciFS_IOC_GET_ENCRYPTION_POLICY only supports the original policy 6408c2ecf20Sopenharmony_civersion. It takes in a pointer directly to struct fscrypt_policy_v1 6418c2ecf20Sopenharmony_cirather than struct fscrypt_get_policy_ex_arg. 6428c2ecf20Sopenharmony_ci 6438c2ecf20Sopenharmony_ciThe error codes for FS_IOC_GET_ENCRYPTION_POLICY are the same as those 6448c2ecf20Sopenharmony_cifor FS_IOC_GET_ENCRYPTION_POLICY_EX, except that 6458c2ecf20Sopenharmony_ciFS_IOC_GET_ENCRYPTION_POLICY also returns ``EINVAL`` if the file is 6468c2ecf20Sopenharmony_ciencrypted using a newer encryption policy version. 6478c2ecf20Sopenharmony_ci 6488c2ecf20Sopenharmony_ciGetting the per-filesystem salt 6498c2ecf20Sopenharmony_ci------------------------------- 6508c2ecf20Sopenharmony_ci 6518c2ecf20Sopenharmony_ciSome filesystems, such as ext4 and F2FS, also support the deprecated 6528c2ecf20Sopenharmony_ciioctl FS_IOC_GET_ENCRYPTION_PWSALT. This ioctl retrieves a randomly 6538c2ecf20Sopenharmony_cigenerated 16-byte value stored in the filesystem superblock. This 6548c2ecf20Sopenharmony_civalue is intended to used as a salt when deriving an encryption key 6558c2ecf20Sopenharmony_cifrom a passphrase or other low-entropy user credential. 6568c2ecf20Sopenharmony_ci 6578c2ecf20Sopenharmony_ciFS_IOC_GET_ENCRYPTION_PWSALT is deprecated. Instead, prefer to 6588c2ecf20Sopenharmony_cigenerate and manage any needed salt(s) in userspace. 6598c2ecf20Sopenharmony_ci 6608c2ecf20Sopenharmony_ciGetting a file's encryption nonce 6618c2ecf20Sopenharmony_ci--------------------------------- 6628c2ecf20Sopenharmony_ci 6638c2ecf20Sopenharmony_ciSince Linux v5.7, the ioctl FS_IOC_GET_ENCRYPTION_NONCE is supported. 6648c2ecf20Sopenharmony_ciOn encrypted files and directories it gets the inode's 16-byte nonce. 6658c2ecf20Sopenharmony_ciOn unencrypted files and directories, it fails with ENODATA. 6668c2ecf20Sopenharmony_ci 6678c2ecf20Sopenharmony_ciThis ioctl can be useful for automated tests which verify that the 6688c2ecf20Sopenharmony_ciencryption is being done correctly. It is not needed for normal use 6698c2ecf20Sopenharmony_ciof fscrypt. 6708c2ecf20Sopenharmony_ci 6718c2ecf20Sopenharmony_ciAdding keys 6728c2ecf20Sopenharmony_ci----------- 6738c2ecf20Sopenharmony_ci 6748c2ecf20Sopenharmony_ciFS_IOC_ADD_ENCRYPTION_KEY 6758c2ecf20Sopenharmony_ci~~~~~~~~~~~~~~~~~~~~~~~~~ 6768c2ecf20Sopenharmony_ci 6778c2ecf20Sopenharmony_ciThe FS_IOC_ADD_ENCRYPTION_KEY ioctl adds a master encryption key to 6788c2ecf20Sopenharmony_cithe filesystem, making all files on the filesystem which were 6798c2ecf20Sopenharmony_ciencrypted using that key appear "unlocked", i.e. in plaintext form. 6808c2ecf20Sopenharmony_ciIt can be executed on any file or directory on the target filesystem, 6818c2ecf20Sopenharmony_cibut using the filesystem's root directory is recommended. It takes in 6828c2ecf20Sopenharmony_cia pointer to struct fscrypt_add_key_arg, defined as follows:: 6838c2ecf20Sopenharmony_ci 6848c2ecf20Sopenharmony_ci struct fscrypt_add_key_arg { 6858c2ecf20Sopenharmony_ci struct fscrypt_key_specifier key_spec; 6868c2ecf20Sopenharmony_ci __u32 raw_size; 6878c2ecf20Sopenharmony_ci __u32 key_id; 6888c2ecf20Sopenharmony_ci __u32 __reserved[8]; 6898c2ecf20Sopenharmony_ci __u8 raw[]; 6908c2ecf20Sopenharmony_ci }; 6918c2ecf20Sopenharmony_ci 6928c2ecf20Sopenharmony_ci #define FSCRYPT_KEY_SPEC_TYPE_DESCRIPTOR 1 6938c2ecf20Sopenharmony_ci #define FSCRYPT_KEY_SPEC_TYPE_IDENTIFIER 2 6948c2ecf20Sopenharmony_ci 6958c2ecf20Sopenharmony_ci struct fscrypt_key_specifier { 6968c2ecf20Sopenharmony_ci __u32 type; /* one of FSCRYPT_KEY_SPEC_TYPE_* */ 6978c2ecf20Sopenharmony_ci __u32 __reserved; 6988c2ecf20Sopenharmony_ci union { 6998c2ecf20Sopenharmony_ci __u8 __reserved[32]; /* reserve some extra space */ 7008c2ecf20Sopenharmony_ci __u8 descriptor[FSCRYPT_KEY_DESCRIPTOR_SIZE]; 7018c2ecf20Sopenharmony_ci __u8 identifier[FSCRYPT_KEY_IDENTIFIER_SIZE]; 7028c2ecf20Sopenharmony_ci } u; 7038c2ecf20Sopenharmony_ci }; 7048c2ecf20Sopenharmony_ci 7058c2ecf20Sopenharmony_ci struct fscrypt_provisioning_key_payload { 7068c2ecf20Sopenharmony_ci __u32 type; 7078c2ecf20Sopenharmony_ci __u32 __reserved; 7088c2ecf20Sopenharmony_ci __u8 raw[]; 7098c2ecf20Sopenharmony_ci }; 7108c2ecf20Sopenharmony_ci 7118c2ecf20Sopenharmony_cistruct fscrypt_add_key_arg must be zeroed, then initialized 7128c2ecf20Sopenharmony_cias follows: 7138c2ecf20Sopenharmony_ci 7148c2ecf20Sopenharmony_ci- If the key is being added for use by v1 encryption policies, then 7158c2ecf20Sopenharmony_ci ``key_spec.type`` must contain FSCRYPT_KEY_SPEC_TYPE_DESCRIPTOR, and 7168c2ecf20Sopenharmony_ci ``key_spec.u.descriptor`` must contain the descriptor of the key 7178c2ecf20Sopenharmony_ci being added, corresponding to the value in the 7188c2ecf20Sopenharmony_ci ``master_key_descriptor`` field of struct fscrypt_policy_v1. 7198c2ecf20Sopenharmony_ci To add this type of key, the calling process must have the 7208c2ecf20Sopenharmony_ci CAP_SYS_ADMIN capability in the initial user namespace. 7218c2ecf20Sopenharmony_ci 7228c2ecf20Sopenharmony_ci Alternatively, if the key is being added for use by v2 encryption 7238c2ecf20Sopenharmony_ci policies, then ``key_spec.type`` must contain 7248c2ecf20Sopenharmony_ci FSCRYPT_KEY_SPEC_TYPE_IDENTIFIER, and ``key_spec.u.identifier`` is 7258c2ecf20Sopenharmony_ci an *output* field which the kernel fills in with a cryptographic 7268c2ecf20Sopenharmony_ci hash of the key. To add this type of key, the calling process does 7278c2ecf20Sopenharmony_ci not need any privileges. However, the number of keys that can be 7288c2ecf20Sopenharmony_ci added is limited by the user's quota for the keyrings service (see 7298c2ecf20Sopenharmony_ci ``Documentation/security/keys/core.rst``). 7308c2ecf20Sopenharmony_ci 7318c2ecf20Sopenharmony_ci- ``raw_size`` must be the size of the ``raw`` key provided, in bytes. 7328c2ecf20Sopenharmony_ci Alternatively, if ``key_id`` is nonzero, this field must be 0, since 7338c2ecf20Sopenharmony_ci in that case the size is implied by the specified Linux keyring key. 7348c2ecf20Sopenharmony_ci 7358c2ecf20Sopenharmony_ci- ``key_id`` is 0 if the raw key is given directly in the ``raw`` 7368c2ecf20Sopenharmony_ci field. Otherwise ``key_id`` is the ID of a Linux keyring key of 7378c2ecf20Sopenharmony_ci type "fscrypt-provisioning" whose payload is 7388c2ecf20Sopenharmony_ci struct fscrypt_provisioning_key_payload whose ``raw`` field contains 7398c2ecf20Sopenharmony_ci the raw key and whose ``type`` field matches ``key_spec.type``. 7408c2ecf20Sopenharmony_ci Since ``raw`` is variable-length, the total size of this key's 7418c2ecf20Sopenharmony_ci payload must be ``sizeof(struct fscrypt_provisioning_key_payload)`` 7428c2ecf20Sopenharmony_ci plus the raw key size. The process must have Search permission on 7438c2ecf20Sopenharmony_ci this key. 7448c2ecf20Sopenharmony_ci 7458c2ecf20Sopenharmony_ci Most users should leave this 0 and specify the raw key directly. 7468c2ecf20Sopenharmony_ci The support for specifying a Linux keyring key is intended mainly to 7478c2ecf20Sopenharmony_ci allow re-adding keys after a filesystem is unmounted and re-mounted, 7488c2ecf20Sopenharmony_ci without having to store the raw keys in userspace memory. 7498c2ecf20Sopenharmony_ci 7508c2ecf20Sopenharmony_ci- ``raw`` is a variable-length field which must contain the actual 7518c2ecf20Sopenharmony_ci key, ``raw_size`` bytes long. Alternatively, if ``key_id`` is 7528c2ecf20Sopenharmony_ci nonzero, then this field is unused. 7538c2ecf20Sopenharmony_ci 7548c2ecf20Sopenharmony_ciFor v2 policy keys, the kernel keeps track of which user (identified 7558c2ecf20Sopenharmony_ciby effective user ID) added the key, and only allows the key to be 7568c2ecf20Sopenharmony_ciremoved by that user --- or by "root", if they use 7578c2ecf20Sopenharmony_ci`FS_IOC_REMOVE_ENCRYPTION_KEY_ALL_USERS`_. 7588c2ecf20Sopenharmony_ci 7598c2ecf20Sopenharmony_ciHowever, if another user has added the key, it may be desirable to 7608c2ecf20Sopenharmony_ciprevent that other user from unexpectedly removing it. Therefore, 7618c2ecf20Sopenharmony_ciFS_IOC_ADD_ENCRYPTION_KEY may also be used to add a v2 policy key 7628c2ecf20Sopenharmony_ci*again*, even if it's already added by other user(s). In this case, 7638c2ecf20Sopenharmony_ciFS_IOC_ADD_ENCRYPTION_KEY will just install a claim to the key for the 7648c2ecf20Sopenharmony_cicurrent user, rather than actually add the key again (but the raw key 7658c2ecf20Sopenharmony_cimust still be provided, as a proof of knowledge). 7668c2ecf20Sopenharmony_ci 7678c2ecf20Sopenharmony_ciFS_IOC_ADD_ENCRYPTION_KEY returns 0 if either the key or a claim to 7688c2ecf20Sopenharmony_cithe key was either added or already exists. 7698c2ecf20Sopenharmony_ci 7708c2ecf20Sopenharmony_ciFS_IOC_ADD_ENCRYPTION_KEY can fail with the following errors: 7718c2ecf20Sopenharmony_ci 7728c2ecf20Sopenharmony_ci- ``EACCES``: FSCRYPT_KEY_SPEC_TYPE_DESCRIPTOR was specified, but the 7738c2ecf20Sopenharmony_ci caller does not have the CAP_SYS_ADMIN capability in the initial 7748c2ecf20Sopenharmony_ci user namespace; or the raw key was specified by Linux key ID but the 7758c2ecf20Sopenharmony_ci process lacks Search permission on the key. 7768c2ecf20Sopenharmony_ci- ``EDQUOT``: the key quota for this user would be exceeded by adding 7778c2ecf20Sopenharmony_ci the key 7788c2ecf20Sopenharmony_ci- ``EINVAL``: invalid key size or key specifier type, or reserved bits 7798c2ecf20Sopenharmony_ci were set 7808c2ecf20Sopenharmony_ci- ``EKEYREJECTED``: the raw key was specified by Linux key ID, but the 7818c2ecf20Sopenharmony_ci key has the wrong type 7828c2ecf20Sopenharmony_ci- ``ENOKEY``: the raw key was specified by Linux key ID, but no key 7838c2ecf20Sopenharmony_ci exists with that ID 7848c2ecf20Sopenharmony_ci- ``ENOTTY``: this type of filesystem does not implement encryption 7858c2ecf20Sopenharmony_ci- ``EOPNOTSUPP``: the kernel was not configured with encryption 7868c2ecf20Sopenharmony_ci support for this filesystem, or the filesystem superblock has not 7878c2ecf20Sopenharmony_ci had encryption enabled on it 7888c2ecf20Sopenharmony_ci 7898c2ecf20Sopenharmony_ciLegacy method 7908c2ecf20Sopenharmony_ci~~~~~~~~~~~~~ 7918c2ecf20Sopenharmony_ci 7928c2ecf20Sopenharmony_ciFor v1 encryption policies, a master encryption key can also be 7938c2ecf20Sopenharmony_ciprovided by adding it to a process-subscribed keyring, e.g. to a 7948c2ecf20Sopenharmony_cisession keyring, or to a user keyring if the user keyring is linked 7958c2ecf20Sopenharmony_ciinto the session keyring. 7968c2ecf20Sopenharmony_ci 7978c2ecf20Sopenharmony_ciThis method is deprecated (and not supported for v2 encryption 7988c2ecf20Sopenharmony_cipolicies) for several reasons. First, it cannot be used in 7998c2ecf20Sopenharmony_cicombination with FS_IOC_REMOVE_ENCRYPTION_KEY (see `Removing keys`_), 8008c2ecf20Sopenharmony_ciso for removing a key a workaround such as keyctl_unlink() in 8018c2ecf20Sopenharmony_cicombination with ``sync; echo 2 > /proc/sys/vm/drop_caches`` would 8028c2ecf20Sopenharmony_cihave to be used. Second, it doesn't match the fact that the 8038c2ecf20Sopenharmony_cilocked/unlocked status of encrypted files (i.e. whether they appear to 8048c2ecf20Sopenharmony_cibe in plaintext form or in ciphertext form) is global. This mismatch 8058c2ecf20Sopenharmony_cihas caused much confusion as well as real problems when processes 8068c2ecf20Sopenharmony_cirunning under different UIDs, such as a ``sudo`` command, need to 8078c2ecf20Sopenharmony_ciaccess encrypted files. 8088c2ecf20Sopenharmony_ci 8098c2ecf20Sopenharmony_ciNevertheless, to add a key to one of the process-subscribed keyrings, 8108c2ecf20Sopenharmony_cithe add_key() system call can be used (see: 8118c2ecf20Sopenharmony_ci``Documentation/security/keys/core.rst``). The key type must be 8128c2ecf20Sopenharmony_ci"logon"; keys of this type are kept in kernel memory and cannot be 8138c2ecf20Sopenharmony_ciread back by userspace. The key description must be "fscrypt:" 8148c2ecf20Sopenharmony_cifollowed by the 16-character lower case hex representation of the 8158c2ecf20Sopenharmony_ci``master_key_descriptor`` that was set in the encryption policy. The 8168c2ecf20Sopenharmony_cikey payload must conform to the following structure:: 8178c2ecf20Sopenharmony_ci 8188c2ecf20Sopenharmony_ci #define FSCRYPT_MAX_KEY_SIZE 64 8198c2ecf20Sopenharmony_ci 8208c2ecf20Sopenharmony_ci struct fscrypt_key { 8218c2ecf20Sopenharmony_ci __u32 mode; 8228c2ecf20Sopenharmony_ci __u8 raw[FSCRYPT_MAX_KEY_SIZE]; 8238c2ecf20Sopenharmony_ci __u32 size; 8248c2ecf20Sopenharmony_ci }; 8258c2ecf20Sopenharmony_ci 8268c2ecf20Sopenharmony_ci``mode`` is ignored; just set it to 0. The actual key is provided in 8278c2ecf20Sopenharmony_ci``raw`` with ``size`` indicating its size in bytes. That is, the 8288c2ecf20Sopenharmony_cibytes ``raw[0..size-1]`` (inclusive) are the actual key. 8298c2ecf20Sopenharmony_ci 8308c2ecf20Sopenharmony_ciThe key description prefix "fscrypt:" may alternatively be replaced 8318c2ecf20Sopenharmony_ciwith a filesystem-specific prefix such as "ext4:". However, the 8328c2ecf20Sopenharmony_cifilesystem-specific prefixes are deprecated and should not be used in 8338c2ecf20Sopenharmony_cinew programs. 8348c2ecf20Sopenharmony_ci 8358c2ecf20Sopenharmony_ciRemoving keys 8368c2ecf20Sopenharmony_ci------------- 8378c2ecf20Sopenharmony_ci 8388c2ecf20Sopenharmony_ciTwo ioctls are available for removing a key that was added by 8398c2ecf20Sopenharmony_ci`FS_IOC_ADD_ENCRYPTION_KEY`_: 8408c2ecf20Sopenharmony_ci 8418c2ecf20Sopenharmony_ci- `FS_IOC_REMOVE_ENCRYPTION_KEY`_ 8428c2ecf20Sopenharmony_ci- `FS_IOC_REMOVE_ENCRYPTION_KEY_ALL_USERS`_ 8438c2ecf20Sopenharmony_ci 8448c2ecf20Sopenharmony_ciThese two ioctls differ only in cases where v2 policy keys are added 8458c2ecf20Sopenharmony_cior removed by non-root users. 8468c2ecf20Sopenharmony_ci 8478c2ecf20Sopenharmony_ciThese ioctls don't work on keys that were added via the legacy 8488c2ecf20Sopenharmony_ciprocess-subscribed keyrings mechanism. 8498c2ecf20Sopenharmony_ci 8508c2ecf20Sopenharmony_ciBefore using these ioctls, read the `Kernel memory compromise`_ 8518c2ecf20Sopenharmony_cisection for a discussion of the security goals and limitations of 8528c2ecf20Sopenharmony_cithese ioctls. 8538c2ecf20Sopenharmony_ci 8548c2ecf20Sopenharmony_ciFS_IOC_REMOVE_ENCRYPTION_KEY 8558c2ecf20Sopenharmony_ci~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 8568c2ecf20Sopenharmony_ci 8578c2ecf20Sopenharmony_ciThe FS_IOC_REMOVE_ENCRYPTION_KEY ioctl removes a claim to a master 8588c2ecf20Sopenharmony_ciencryption key from the filesystem, and possibly removes the key 8598c2ecf20Sopenharmony_ciitself. It can be executed on any file or directory on the target 8608c2ecf20Sopenharmony_cifilesystem, but using the filesystem's root directory is recommended. 8618c2ecf20Sopenharmony_ciIt takes in a pointer to struct fscrypt_remove_key_arg, defined 8628c2ecf20Sopenharmony_cias follows:: 8638c2ecf20Sopenharmony_ci 8648c2ecf20Sopenharmony_ci struct fscrypt_remove_key_arg { 8658c2ecf20Sopenharmony_ci struct fscrypt_key_specifier key_spec; 8668c2ecf20Sopenharmony_ci #define FSCRYPT_KEY_REMOVAL_STATUS_FLAG_FILES_BUSY 0x00000001 8678c2ecf20Sopenharmony_ci #define FSCRYPT_KEY_REMOVAL_STATUS_FLAG_OTHER_USERS 0x00000002 8688c2ecf20Sopenharmony_ci __u32 removal_status_flags; /* output */ 8698c2ecf20Sopenharmony_ci __u32 __reserved[5]; 8708c2ecf20Sopenharmony_ci }; 8718c2ecf20Sopenharmony_ci 8728c2ecf20Sopenharmony_ciThis structure must be zeroed, then initialized as follows: 8738c2ecf20Sopenharmony_ci 8748c2ecf20Sopenharmony_ci- The key to remove is specified by ``key_spec``: 8758c2ecf20Sopenharmony_ci 8768c2ecf20Sopenharmony_ci - To remove a key used by v1 encryption policies, set 8778c2ecf20Sopenharmony_ci ``key_spec.type`` to FSCRYPT_KEY_SPEC_TYPE_DESCRIPTOR and fill 8788c2ecf20Sopenharmony_ci in ``key_spec.u.descriptor``. To remove this type of key, the 8798c2ecf20Sopenharmony_ci calling process must have the CAP_SYS_ADMIN capability in the 8808c2ecf20Sopenharmony_ci initial user namespace. 8818c2ecf20Sopenharmony_ci 8828c2ecf20Sopenharmony_ci - To remove a key used by v2 encryption policies, set 8838c2ecf20Sopenharmony_ci ``key_spec.type`` to FSCRYPT_KEY_SPEC_TYPE_IDENTIFIER and fill 8848c2ecf20Sopenharmony_ci in ``key_spec.u.identifier``. 8858c2ecf20Sopenharmony_ci 8868c2ecf20Sopenharmony_ciFor v2 policy keys, this ioctl is usable by non-root users. However, 8878c2ecf20Sopenharmony_cito make this possible, it actually just removes the current user's 8888c2ecf20Sopenharmony_ciclaim to the key, undoing a single call to FS_IOC_ADD_ENCRYPTION_KEY. 8898c2ecf20Sopenharmony_ciOnly after all claims are removed is the key really removed. 8908c2ecf20Sopenharmony_ci 8918c2ecf20Sopenharmony_ciFor example, if FS_IOC_ADD_ENCRYPTION_KEY was called with uid 1000, 8928c2ecf20Sopenharmony_cithen the key will be "claimed" by uid 1000, and 8938c2ecf20Sopenharmony_ciFS_IOC_REMOVE_ENCRYPTION_KEY will only succeed as uid 1000. Or, if 8948c2ecf20Sopenharmony_ciboth uids 1000 and 2000 added the key, then for each uid 8958c2ecf20Sopenharmony_ciFS_IOC_REMOVE_ENCRYPTION_KEY will only remove their own claim. Only 8968c2ecf20Sopenharmony_cionce *both* are removed is the key really removed. (Think of it like 8978c2ecf20Sopenharmony_ciunlinking a file that may have hard links.) 8988c2ecf20Sopenharmony_ci 8998c2ecf20Sopenharmony_ciIf FS_IOC_REMOVE_ENCRYPTION_KEY really removes the key, it will also 9008c2ecf20Sopenharmony_citry to "lock" all files that had been unlocked with the key. It won't 9018c2ecf20Sopenharmony_cilock files that are still in-use, so this ioctl is expected to be used 9028c2ecf20Sopenharmony_ciin cooperation with userspace ensuring that none of the files are 9038c2ecf20Sopenharmony_cistill open. However, if necessary, this ioctl can be executed again 9048c2ecf20Sopenharmony_cilater to retry locking any remaining files. 9058c2ecf20Sopenharmony_ci 9068c2ecf20Sopenharmony_ciFS_IOC_REMOVE_ENCRYPTION_KEY returns 0 if either the key was removed 9078c2ecf20Sopenharmony_ci(but may still have files remaining to be locked), the user's claim to 9088c2ecf20Sopenharmony_cithe key was removed, or the key was already removed but had files 9098c2ecf20Sopenharmony_ciremaining to be the locked so the ioctl retried locking them. In any 9108c2ecf20Sopenharmony_ciof these cases, ``removal_status_flags`` is filled in with the 9118c2ecf20Sopenharmony_cifollowing informational status flags: 9128c2ecf20Sopenharmony_ci 9138c2ecf20Sopenharmony_ci- ``FSCRYPT_KEY_REMOVAL_STATUS_FLAG_FILES_BUSY``: set if some file(s) 9148c2ecf20Sopenharmony_ci are still in-use. Not guaranteed to be set in the case where only 9158c2ecf20Sopenharmony_ci the user's claim to the key was removed. 9168c2ecf20Sopenharmony_ci- ``FSCRYPT_KEY_REMOVAL_STATUS_FLAG_OTHER_USERS``: set if only the 9178c2ecf20Sopenharmony_ci user's claim to the key was removed, not the key itself 9188c2ecf20Sopenharmony_ci 9198c2ecf20Sopenharmony_ciFS_IOC_REMOVE_ENCRYPTION_KEY can fail with the following errors: 9208c2ecf20Sopenharmony_ci 9218c2ecf20Sopenharmony_ci- ``EACCES``: The FSCRYPT_KEY_SPEC_TYPE_DESCRIPTOR key specifier type 9228c2ecf20Sopenharmony_ci was specified, but the caller does not have the CAP_SYS_ADMIN 9238c2ecf20Sopenharmony_ci capability in the initial user namespace 9248c2ecf20Sopenharmony_ci- ``EINVAL``: invalid key specifier type, or reserved bits were set 9258c2ecf20Sopenharmony_ci- ``ENOKEY``: the key object was not found at all, i.e. it was never 9268c2ecf20Sopenharmony_ci added in the first place or was already fully removed including all 9278c2ecf20Sopenharmony_ci files locked; or, the user does not have a claim to the key (but 9288c2ecf20Sopenharmony_ci someone else does). 9298c2ecf20Sopenharmony_ci- ``ENOTTY``: this type of filesystem does not implement encryption 9308c2ecf20Sopenharmony_ci- ``EOPNOTSUPP``: the kernel was not configured with encryption 9318c2ecf20Sopenharmony_ci support for this filesystem, or the filesystem superblock has not 9328c2ecf20Sopenharmony_ci had encryption enabled on it 9338c2ecf20Sopenharmony_ci 9348c2ecf20Sopenharmony_ciFS_IOC_REMOVE_ENCRYPTION_KEY_ALL_USERS 9358c2ecf20Sopenharmony_ci~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 9368c2ecf20Sopenharmony_ci 9378c2ecf20Sopenharmony_ciFS_IOC_REMOVE_ENCRYPTION_KEY_ALL_USERS is exactly the same as 9388c2ecf20Sopenharmony_ci`FS_IOC_REMOVE_ENCRYPTION_KEY`_, except that for v2 policy keys, the 9398c2ecf20Sopenharmony_ciALL_USERS version of the ioctl will remove all users' claims to the 9408c2ecf20Sopenharmony_cikey, not just the current user's. I.e., the key itself will always be 9418c2ecf20Sopenharmony_ciremoved, no matter how many users have added it. This difference is 9428c2ecf20Sopenharmony_cionly meaningful if non-root users are adding and removing keys. 9438c2ecf20Sopenharmony_ci 9448c2ecf20Sopenharmony_ciBecause of this, FS_IOC_REMOVE_ENCRYPTION_KEY_ALL_USERS also requires 9458c2ecf20Sopenharmony_ci"root", namely the CAP_SYS_ADMIN capability in the initial user 9468c2ecf20Sopenharmony_cinamespace. Otherwise it will fail with EACCES. 9478c2ecf20Sopenharmony_ci 9488c2ecf20Sopenharmony_ciGetting key status 9498c2ecf20Sopenharmony_ci------------------ 9508c2ecf20Sopenharmony_ci 9518c2ecf20Sopenharmony_ciFS_IOC_GET_ENCRYPTION_KEY_STATUS 9528c2ecf20Sopenharmony_ci~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 9538c2ecf20Sopenharmony_ci 9548c2ecf20Sopenharmony_ciThe FS_IOC_GET_ENCRYPTION_KEY_STATUS ioctl retrieves the status of a 9558c2ecf20Sopenharmony_cimaster encryption key. It can be executed on any file or directory on 9568c2ecf20Sopenharmony_cithe target filesystem, but using the filesystem's root directory is 9578c2ecf20Sopenharmony_cirecommended. It takes in a pointer to 9588c2ecf20Sopenharmony_cistruct fscrypt_get_key_status_arg, defined as follows:: 9598c2ecf20Sopenharmony_ci 9608c2ecf20Sopenharmony_ci struct fscrypt_get_key_status_arg { 9618c2ecf20Sopenharmony_ci /* input */ 9628c2ecf20Sopenharmony_ci struct fscrypt_key_specifier key_spec; 9638c2ecf20Sopenharmony_ci __u32 __reserved[6]; 9648c2ecf20Sopenharmony_ci 9658c2ecf20Sopenharmony_ci /* output */ 9668c2ecf20Sopenharmony_ci #define FSCRYPT_KEY_STATUS_ABSENT 1 9678c2ecf20Sopenharmony_ci #define FSCRYPT_KEY_STATUS_PRESENT 2 9688c2ecf20Sopenharmony_ci #define FSCRYPT_KEY_STATUS_INCOMPLETELY_REMOVED 3 9698c2ecf20Sopenharmony_ci __u32 status; 9708c2ecf20Sopenharmony_ci #define FSCRYPT_KEY_STATUS_FLAG_ADDED_BY_SELF 0x00000001 9718c2ecf20Sopenharmony_ci __u32 status_flags; 9728c2ecf20Sopenharmony_ci __u32 user_count; 9738c2ecf20Sopenharmony_ci __u32 __out_reserved[13]; 9748c2ecf20Sopenharmony_ci }; 9758c2ecf20Sopenharmony_ci 9768c2ecf20Sopenharmony_ciThe caller must zero all input fields, then fill in ``key_spec``: 9778c2ecf20Sopenharmony_ci 9788c2ecf20Sopenharmony_ci - To get the status of a key for v1 encryption policies, set 9798c2ecf20Sopenharmony_ci ``key_spec.type`` to FSCRYPT_KEY_SPEC_TYPE_DESCRIPTOR and fill 9808c2ecf20Sopenharmony_ci in ``key_spec.u.descriptor``. 9818c2ecf20Sopenharmony_ci 9828c2ecf20Sopenharmony_ci - To get the status of a key for v2 encryption policies, set 9838c2ecf20Sopenharmony_ci ``key_spec.type`` to FSCRYPT_KEY_SPEC_TYPE_IDENTIFIER and fill 9848c2ecf20Sopenharmony_ci in ``key_spec.u.identifier``. 9858c2ecf20Sopenharmony_ci 9868c2ecf20Sopenharmony_ciOn success, 0 is returned and the kernel fills in the output fields: 9878c2ecf20Sopenharmony_ci 9888c2ecf20Sopenharmony_ci- ``status`` indicates whether the key is absent, present, or 9898c2ecf20Sopenharmony_ci incompletely removed. Incompletely removed means that the master 9908c2ecf20Sopenharmony_ci secret has been removed, but some files are still in use; i.e., 9918c2ecf20Sopenharmony_ci `FS_IOC_REMOVE_ENCRYPTION_KEY`_ returned 0 but set the informational 9928c2ecf20Sopenharmony_ci status flag FSCRYPT_KEY_REMOVAL_STATUS_FLAG_FILES_BUSY. 9938c2ecf20Sopenharmony_ci 9948c2ecf20Sopenharmony_ci- ``status_flags`` can contain the following flags: 9958c2ecf20Sopenharmony_ci 9968c2ecf20Sopenharmony_ci - ``FSCRYPT_KEY_STATUS_FLAG_ADDED_BY_SELF`` indicates that the key 9978c2ecf20Sopenharmony_ci has added by the current user. This is only set for keys 9988c2ecf20Sopenharmony_ci identified by ``identifier`` rather than by ``descriptor``. 9998c2ecf20Sopenharmony_ci 10008c2ecf20Sopenharmony_ci- ``user_count`` specifies the number of users who have added the key. 10018c2ecf20Sopenharmony_ci This is only set for keys identified by ``identifier`` rather than 10028c2ecf20Sopenharmony_ci by ``descriptor``. 10038c2ecf20Sopenharmony_ci 10048c2ecf20Sopenharmony_ciFS_IOC_GET_ENCRYPTION_KEY_STATUS can fail with the following errors: 10058c2ecf20Sopenharmony_ci 10068c2ecf20Sopenharmony_ci- ``EINVAL``: invalid key specifier type, or reserved bits were set 10078c2ecf20Sopenharmony_ci- ``ENOTTY``: this type of filesystem does not implement encryption 10088c2ecf20Sopenharmony_ci- ``EOPNOTSUPP``: the kernel was not configured with encryption 10098c2ecf20Sopenharmony_ci support for this filesystem, or the filesystem superblock has not 10108c2ecf20Sopenharmony_ci had encryption enabled on it 10118c2ecf20Sopenharmony_ci 10128c2ecf20Sopenharmony_ciAmong other use cases, FS_IOC_GET_ENCRYPTION_KEY_STATUS can be useful 10138c2ecf20Sopenharmony_cifor determining whether the key for a given encrypted directory needs 10148c2ecf20Sopenharmony_cito be added before prompting the user for the passphrase needed to 10158c2ecf20Sopenharmony_ciderive the key. 10168c2ecf20Sopenharmony_ci 10178c2ecf20Sopenharmony_ciFS_IOC_GET_ENCRYPTION_KEY_STATUS can only get the status of keys in 10188c2ecf20Sopenharmony_cithe filesystem-level keyring, i.e. the keyring managed by 10198c2ecf20Sopenharmony_ci`FS_IOC_ADD_ENCRYPTION_KEY`_ and `FS_IOC_REMOVE_ENCRYPTION_KEY`_. It 10208c2ecf20Sopenharmony_cicannot get the status of a key that has only been added for use by v1 10218c2ecf20Sopenharmony_ciencryption policies using the legacy mechanism involving 10228c2ecf20Sopenharmony_ciprocess-subscribed keyrings. 10238c2ecf20Sopenharmony_ci 10248c2ecf20Sopenharmony_ciAccess semantics 10258c2ecf20Sopenharmony_ci================ 10268c2ecf20Sopenharmony_ci 10278c2ecf20Sopenharmony_ciWith the key 10288c2ecf20Sopenharmony_ci------------ 10298c2ecf20Sopenharmony_ci 10308c2ecf20Sopenharmony_ciWith the encryption key, encrypted regular files, directories, and 10318c2ecf20Sopenharmony_cisymlinks behave very similarly to their unencrypted counterparts --- 10328c2ecf20Sopenharmony_ciafter all, the encryption is intended to be transparent. However, 10338c2ecf20Sopenharmony_ciastute users may notice some differences in behavior: 10348c2ecf20Sopenharmony_ci 10358c2ecf20Sopenharmony_ci- Unencrypted files, or files encrypted with a different encryption 10368c2ecf20Sopenharmony_ci policy (i.e. different key, modes, or flags), cannot be renamed or 10378c2ecf20Sopenharmony_ci linked into an encrypted directory; see `Encryption policy 10388c2ecf20Sopenharmony_ci enforcement`_. Attempts to do so will fail with EXDEV. However, 10398c2ecf20Sopenharmony_ci encrypted files can be renamed within an encrypted directory, or 10408c2ecf20Sopenharmony_ci into an unencrypted directory. 10418c2ecf20Sopenharmony_ci 10428c2ecf20Sopenharmony_ci Note: "moving" an unencrypted file into an encrypted directory, e.g. 10438c2ecf20Sopenharmony_ci with the `mv` program, is implemented in userspace by a copy 10448c2ecf20Sopenharmony_ci followed by a delete. Be aware that the original unencrypted data 10458c2ecf20Sopenharmony_ci may remain recoverable from free space on the disk; prefer to keep 10468c2ecf20Sopenharmony_ci all files encrypted from the very beginning. The `shred` program 10478c2ecf20Sopenharmony_ci may be used to overwrite the source files but isn't guaranteed to be 10488c2ecf20Sopenharmony_ci effective on all filesystems and storage devices. 10498c2ecf20Sopenharmony_ci 10508c2ecf20Sopenharmony_ci- Direct I/O is not supported on encrypted files. Attempts to use 10518c2ecf20Sopenharmony_ci direct I/O on such files will fall back to buffered I/O. 10528c2ecf20Sopenharmony_ci 10538c2ecf20Sopenharmony_ci- The fallocate operations FALLOC_FL_COLLAPSE_RANGE and 10548c2ecf20Sopenharmony_ci FALLOC_FL_INSERT_RANGE are not supported on encrypted files and will 10558c2ecf20Sopenharmony_ci fail with EOPNOTSUPP. 10568c2ecf20Sopenharmony_ci 10578c2ecf20Sopenharmony_ci- Online defragmentation of encrypted files is not supported. The 10588c2ecf20Sopenharmony_ci EXT4_IOC_MOVE_EXT and F2FS_IOC_MOVE_RANGE ioctls will fail with 10598c2ecf20Sopenharmony_ci EOPNOTSUPP. 10608c2ecf20Sopenharmony_ci 10618c2ecf20Sopenharmony_ci- The ext4 filesystem does not support data journaling with encrypted 10628c2ecf20Sopenharmony_ci regular files. It will fall back to ordered data mode instead. 10638c2ecf20Sopenharmony_ci 10648c2ecf20Sopenharmony_ci- DAX (Direct Access) is not supported on encrypted files. 10658c2ecf20Sopenharmony_ci 10668c2ecf20Sopenharmony_ci- The st_size of an encrypted symlink will not necessarily give the 10678c2ecf20Sopenharmony_ci length of the symlink target as required by POSIX. It will actually 10688c2ecf20Sopenharmony_ci give the length of the ciphertext, which will be slightly longer 10698c2ecf20Sopenharmony_ci than the plaintext due to NUL-padding and an extra 2-byte overhead. 10708c2ecf20Sopenharmony_ci 10718c2ecf20Sopenharmony_ci- The maximum length of an encrypted symlink is 2 bytes shorter than 10728c2ecf20Sopenharmony_ci the maximum length of an unencrypted symlink. For example, on an 10738c2ecf20Sopenharmony_ci EXT4 filesystem with a 4K block size, unencrypted symlinks can be up 10748c2ecf20Sopenharmony_ci to 4095 bytes long, while encrypted symlinks can only be up to 4093 10758c2ecf20Sopenharmony_ci bytes long (both lengths excluding the terminating null). 10768c2ecf20Sopenharmony_ci 10778c2ecf20Sopenharmony_ciNote that mmap *is* supported. This is possible because the pagecache 10788c2ecf20Sopenharmony_cifor an encrypted file contains the plaintext, not the ciphertext. 10798c2ecf20Sopenharmony_ci 10808c2ecf20Sopenharmony_ciWithout the key 10818c2ecf20Sopenharmony_ci--------------- 10828c2ecf20Sopenharmony_ci 10838c2ecf20Sopenharmony_ciSome filesystem operations may be performed on encrypted regular 10848c2ecf20Sopenharmony_cifiles, directories, and symlinks even before their encryption key has 10858c2ecf20Sopenharmony_cibeen added, or after their encryption key has been removed: 10868c2ecf20Sopenharmony_ci 10878c2ecf20Sopenharmony_ci- File metadata may be read, e.g. using stat(). 10888c2ecf20Sopenharmony_ci 10898c2ecf20Sopenharmony_ci- Directories may be listed, in which case the filenames will be 10908c2ecf20Sopenharmony_ci listed in an encoded form derived from their ciphertext. The 10918c2ecf20Sopenharmony_ci current encoding algorithm is described in `Filename hashing and 10928c2ecf20Sopenharmony_ci encoding`_. The algorithm is subject to change, but it is 10938c2ecf20Sopenharmony_ci guaranteed that the presented filenames will be no longer than 10948c2ecf20Sopenharmony_ci NAME_MAX bytes, will not contain the ``/`` or ``\0`` characters, and 10958c2ecf20Sopenharmony_ci will uniquely identify directory entries. 10968c2ecf20Sopenharmony_ci 10978c2ecf20Sopenharmony_ci The ``.`` and ``..`` directory entries are special. They are always 10988c2ecf20Sopenharmony_ci present and are not encrypted or encoded. 10998c2ecf20Sopenharmony_ci 11008c2ecf20Sopenharmony_ci- Files may be deleted. That is, nondirectory files may be deleted 11018c2ecf20Sopenharmony_ci with unlink() as usual, and empty directories may be deleted with 11028c2ecf20Sopenharmony_ci rmdir() as usual. Therefore, ``rm`` and ``rm -r`` will work as 11038c2ecf20Sopenharmony_ci expected. 11048c2ecf20Sopenharmony_ci 11058c2ecf20Sopenharmony_ci- Symlink targets may be read and followed, but they will be presented 11068c2ecf20Sopenharmony_ci in encrypted form, similar to filenames in directories. Hence, they 11078c2ecf20Sopenharmony_ci are unlikely to point to anywhere useful. 11088c2ecf20Sopenharmony_ci 11098c2ecf20Sopenharmony_ciWithout the key, regular files cannot be opened or truncated. 11108c2ecf20Sopenharmony_ciAttempts to do so will fail with ENOKEY. This implies that any 11118c2ecf20Sopenharmony_ciregular file operations that require a file descriptor, such as 11128c2ecf20Sopenharmony_ciread(), write(), mmap(), fallocate(), and ioctl(), are also forbidden. 11138c2ecf20Sopenharmony_ci 11148c2ecf20Sopenharmony_ciAlso without the key, files of any type (including directories) cannot 11158c2ecf20Sopenharmony_cibe created or linked into an encrypted directory, nor can a name in an 11168c2ecf20Sopenharmony_ciencrypted directory be the source or target of a rename, nor can an 11178c2ecf20Sopenharmony_ciO_TMPFILE temporary file be created in an encrypted directory. All 11188c2ecf20Sopenharmony_cisuch operations will fail with ENOKEY. 11198c2ecf20Sopenharmony_ci 11208c2ecf20Sopenharmony_ciIt is not currently possible to backup and restore encrypted files 11218c2ecf20Sopenharmony_ciwithout the encryption key. This would require special APIs which 11228c2ecf20Sopenharmony_cihave not yet been implemented. 11238c2ecf20Sopenharmony_ci 11248c2ecf20Sopenharmony_ciEncryption policy enforcement 11258c2ecf20Sopenharmony_ci============================= 11268c2ecf20Sopenharmony_ci 11278c2ecf20Sopenharmony_ciAfter an encryption policy has been set on a directory, all regular 11288c2ecf20Sopenharmony_cifiles, directories, and symbolic links created in that directory 11298c2ecf20Sopenharmony_ci(recursively) will inherit that encryption policy. Special files --- 11308c2ecf20Sopenharmony_cithat is, named pipes, device nodes, and UNIX domain sockets --- will 11318c2ecf20Sopenharmony_cinot be encrypted. 11328c2ecf20Sopenharmony_ci 11338c2ecf20Sopenharmony_ciExcept for those special files, it is forbidden to have unencrypted 11348c2ecf20Sopenharmony_cifiles, or files encrypted with a different encryption policy, in an 11358c2ecf20Sopenharmony_ciencrypted directory tree. Attempts to link or rename such a file into 11368c2ecf20Sopenharmony_cian encrypted directory will fail with EXDEV. This is also enforced 11378c2ecf20Sopenharmony_ciduring ->lookup() to provide limited protection against offline 11388c2ecf20Sopenharmony_ciattacks that try to disable or downgrade encryption in known locations 11398c2ecf20Sopenharmony_ciwhere applications may later write sensitive data. It is recommended 11408c2ecf20Sopenharmony_cithat systems implementing a form of "verified boot" take advantage of 11418c2ecf20Sopenharmony_cithis by validating all top-level encryption policies prior to access. 11428c2ecf20Sopenharmony_ci 11438c2ecf20Sopenharmony_ciImplementation details 11448c2ecf20Sopenharmony_ci====================== 11458c2ecf20Sopenharmony_ci 11468c2ecf20Sopenharmony_ciEncryption context 11478c2ecf20Sopenharmony_ci------------------ 11488c2ecf20Sopenharmony_ci 11498c2ecf20Sopenharmony_ciAn encryption policy is represented on-disk by 11508c2ecf20Sopenharmony_cistruct fscrypt_context_v1 or struct fscrypt_context_v2. It is up to 11518c2ecf20Sopenharmony_ciindividual filesystems to decide where to store it, but normally it 11528c2ecf20Sopenharmony_ciwould be stored in a hidden extended attribute. It should *not* be 11538c2ecf20Sopenharmony_ciexposed by the xattr-related system calls such as getxattr() and 11548c2ecf20Sopenharmony_cisetxattr() because of the special semantics of the encryption xattr. 11558c2ecf20Sopenharmony_ci(In particular, there would be much confusion if an encryption policy 11568c2ecf20Sopenharmony_ciwere to be added to or removed from anything other than an empty 11578c2ecf20Sopenharmony_cidirectory.) These structs are defined as follows:: 11588c2ecf20Sopenharmony_ci 11598c2ecf20Sopenharmony_ci #define FSCRYPT_FILE_NONCE_SIZE 16 11608c2ecf20Sopenharmony_ci 11618c2ecf20Sopenharmony_ci #define FSCRYPT_KEY_DESCRIPTOR_SIZE 8 11628c2ecf20Sopenharmony_ci struct fscrypt_context_v1 { 11638c2ecf20Sopenharmony_ci u8 version; 11648c2ecf20Sopenharmony_ci u8 contents_encryption_mode; 11658c2ecf20Sopenharmony_ci u8 filenames_encryption_mode; 11668c2ecf20Sopenharmony_ci u8 flags; 11678c2ecf20Sopenharmony_ci u8 master_key_descriptor[FSCRYPT_KEY_DESCRIPTOR_SIZE]; 11688c2ecf20Sopenharmony_ci u8 nonce[FSCRYPT_FILE_NONCE_SIZE]; 11698c2ecf20Sopenharmony_ci }; 11708c2ecf20Sopenharmony_ci 11718c2ecf20Sopenharmony_ci #define FSCRYPT_KEY_IDENTIFIER_SIZE 16 11728c2ecf20Sopenharmony_ci struct fscrypt_context_v2 { 11738c2ecf20Sopenharmony_ci u8 version; 11748c2ecf20Sopenharmony_ci u8 contents_encryption_mode; 11758c2ecf20Sopenharmony_ci u8 filenames_encryption_mode; 11768c2ecf20Sopenharmony_ci u8 flags; 11778c2ecf20Sopenharmony_ci u8 __reserved[4]; 11788c2ecf20Sopenharmony_ci u8 master_key_identifier[FSCRYPT_KEY_IDENTIFIER_SIZE]; 11798c2ecf20Sopenharmony_ci u8 nonce[FSCRYPT_FILE_NONCE_SIZE]; 11808c2ecf20Sopenharmony_ci }; 11818c2ecf20Sopenharmony_ci 11828c2ecf20Sopenharmony_ciThe context structs contain the same information as the corresponding 11838c2ecf20Sopenharmony_cipolicy structs (see `Setting an encryption policy`_), except that the 11848c2ecf20Sopenharmony_cicontext structs also contain a nonce. The nonce is randomly generated 11858c2ecf20Sopenharmony_ciby the kernel and is used as KDF input or as a tweak to cause 11868c2ecf20Sopenharmony_cidifferent files to be encrypted differently; see `Per-file encryption 11878c2ecf20Sopenharmony_cikeys`_ and `DIRECT_KEY policies`_. 11888c2ecf20Sopenharmony_ci 11898c2ecf20Sopenharmony_ciData path changes 11908c2ecf20Sopenharmony_ci----------------- 11918c2ecf20Sopenharmony_ci 11928c2ecf20Sopenharmony_ciFor the read path (->readpage()) of regular files, filesystems can 11938c2ecf20Sopenharmony_ciread the ciphertext into the page cache and decrypt it in-place. The 11948c2ecf20Sopenharmony_cipage lock must be held until decryption has finished, to prevent the 11958c2ecf20Sopenharmony_cipage from becoming visible to userspace prematurely. 11968c2ecf20Sopenharmony_ci 11978c2ecf20Sopenharmony_ciFor the write path (->writepage()) of regular files, filesystems 11988c2ecf20Sopenharmony_cicannot encrypt data in-place in the page cache, since the cached 11998c2ecf20Sopenharmony_ciplaintext must be preserved. Instead, filesystems must encrypt into a 12008c2ecf20Sopenharmony_citemporary buffer or "bounce page", then write out the temporary 12018c2ecf20Sopenharmony_cibuffer. Some filesystems, such as UBIFS, already use temporary 12028c2ecf20Sopenharmony_cibuffers regardless of encryption. Other filesystems, such as ext4 and 12038c2ecf20Sopenharmony_ciF2FS, have to allocate bounce pages specially for encryption. 12048c2ecf20Sopenharmony_ci 12058c2ecf20Sopenharmony_ciFscrypt is also able to use inline encryption hardware instead of the 12068c2ecf20Sopenharmony_cikernel crypto API for en/decryption of file contents. When possible, 12078c2ecf20Sopenharmony_ciand if directed to do so (by specifying the 'inlinecrypt' mount option 12088c2ecf20Sopenharmony_cifor an ext4/F2FS filesystem), it adds encryption contexts to bios and 12098c2ecf20Sopenharmony_ciuses blk-crypto to perform the en/decryption instead of making use of 12108c2ecf20Sopenharmony_cithe above read/write path changes. Of course, even if directed to 12118c2ecf20Sopenharmony_cimake use of inline encryption, fscrypt will only be able to do so if 12128c2ecf20Sopenharmony_cieither hardware inline encryption support is available for the 12138c2ecf20Sopenharmony_ciselected encryption algorithm or CONFIG_BLK_INLINE_ENCRYPTION_FALLBACK 12148c2ecf20Sopenharmony_ciis selected. If neither is the case, fscrypt will fall back to using 12158c2ecf20Sopenharmony_cithe above mentioned read/write path changes for en/decryption. 12168c2ecf20Sopenharmony_ci 12178c2ecf20Sopenharmony_ciFilename hashing and encoding 12188c2ecf20Sopenharmony_ci----------------------------- 12198c2ecf20Sopenharmony_ci 12208c2ecf20Sopenharmony_ciModern filesystems accelerate directory lookups by using indexed 12218c2ecf20Sopenharmony_cidirectories. An indexed directory is organized as a tree keyed by 12228c2ecf20Sopenharmony_cifilename hashes. When a ->lookup() is requested, the filesystem 12238c2ecf20Sopenharmony_cinormally hashes the filename being looked up so that it can quickly 12248c2ecf20Sopenharmony_cifind the corresponding directory entry, if any. 12258c2ecf20Sopenharmony_ci 12268c2ecf20Sopenharmony_ciWith encryption, lookups must be supported and efficient both with and 12278c2ecf20Sopenharmony_ciwithout the encryption key. Clearly, it would not work to hash the 12288c2ecf20Sopenharmony_ciplaintext filenames, since the plaintext filenames are unavailable 12298c2ecf20Sopenharmony_ciwithout the key. (Hashing the plaintext filenames would also make it 12308c2ecf20Sopenharmony_ciimpossible for the filesystem's fsck tool to optimize encrypted 12318c2ecf20Sopenharmony_cidirectories.) Instead, filesystems hash the ciphertext filenames, 12328c2ecf20Sopenharmony_cii.e. the bytes actually stored on-disk in the directory entries. When 12338c2ecf20Sopenharmony_ciasked to do a ->lookup() with the key, the filesystem just encrypts 12348c2ecf20Sopenharmony_cithe user-supplied name to get the ciphertext. 12358c2ecf20Sopenharmony_ci 12368c2ecf20Sopenharmony_ciLookups without the key are more complicated. The raw ciphertext may 12378c2ecf20Sopenharmony_cicontain the ``\0`` and ``/`` characters, which are illegal in 12388c2ecf20Sopenharmony_cifilenames. Therefore, readdir() must base64-encode the ciphertext for 12398c2ecf20Sopenharmony_cipresentation. For most filenames, this works fine; on ->lookup(), the 12408c2ecf20Sopenharmony_cifilesystem just base64-decodes the user-supplied name to get back to 12418c2ecf20Sopenharmony_cithe raw ciphertext. 12428c2ecf20Sopenharmony_ci 12438c2ecf20Sopenharmony_ciHowever, for very long filenames, base64 encoding would cause the 12448c2ecf20Sopenharmony_cifilename length to exceed NAME_MAX. To prevent this, readdir() 12458c2ecf20Sopenharmony_ciactually presents long filenames in an abbreviated form which encodes 12468c2ecf20Sopenharmony_cia strong "hash" of the ciphertext filename, along with the optional 12478c2ecf20Sopenharmony_cifilesystem-specific hash(es) needed for directory lookups. This 12488c2ecf20Sopenharmony_ciallows the filesystem to still, with a high degree of confidence, map 12498c2ecf20Sopenharmony_cithe filename given in ->lookup() back to a particular directory entry 12508c2ecf20Sopenharmony_cithat was previously listed by readdir(). See 12518c2ecf20Sopenharmony_cistruct fscrypt_nokey_name in the source for more details. 12528c2ecf20Sopenharmony_ci 12538c2ecf20Sopenharmony_ciNote that the precise way that filenames are presented to userspace 12548c2ecf20Sopenharmony_ciwithout the key is subject to change in the future. It is only meant 12558c2ecf20Sopenharmony_cias a way to temporarily present valid filenames so that commands like 12568c2ecf20Sopenharmony_ci``rm -r`` work as expected on encrypted directories. 12578c2ecf20Sopenharmony_ci 12588c2ecf20Sopenharmony_ciTests 12598c2ecf20Sopenharmony_ci===== 12608c2ecf20Sopenharmony_ci 12618c2ecf20Sopenharmony_ciTo test fscrypt, use xfstests, which is Linux's de facto standard 12628c2ecf20Sopenharmony_cifilesystem test suite. First, run all the tests in the "encrypt" 12638c2ecf20Sopenharmony_cigroup on the relevant filesystem(s). One can also run the tests 12648c2ecf20Sopenharmony_ciwith the 'inlinecrypt' mount option to test the implementation for 12658c2ecf20Sopenharmony_ciinline encryption support. For example, to test ext4 and 12668c2ecf20Sopenharmony_cif2fs encryption using `kvm-xfstests 12678c2ecf20Sopenharmony_ci<https://github.com/tytso/xfstests-bld/blob/master/Documentation/kvm-quickstart.md>`_:: 12688c2ecf20Sopenharmony_ci 12698c2ecf20Sopenharmony_ci kvm-xfstests -c ext4,f2fs -g encrypt 12708c2ecf20Sopenharmony_ci kvm-xfstests -c ext4,f2fs -g encrypt -m inlinecrypt 12718c2ecf20Sopenharmony_ci 12728c2ecf20Sopenharmony_ciUBIFS encryption can also be tested this way, but it should be done in 12738c2ecf20Sopenharmony_cia separate command, and it takes some time for kvm-xfstests to set up 12748c2ecf20Sopenharmony_ciemulated UBI volumes:: 12758c2ecf20Sopenharmony_ci 12768c2ecf20Sopenharmony_ci kvm-xfstests -c ubifs -g encrypt 12778c2ecf20Sopenharmony_ci 12788c2ecf20Sopenharmony_ciNo tests should fail. However, tests that use non-default encryption 12798c2ecf20Sopenharmony_cimodes (e.g. generic/549 and generic/550) will be skipped if the needed 12808c2ecf20Sopenharmony_cialgorithms were not built into the kernel's crypto API. Also, tests 12818c2ecf20Sopenharmony_cithat access the raw block device (e.g. generic/399, generic/548, 12828c2ecf20Sopenharmony_cigeneric/549, generic/550) will be skipped on UBIFS. 12838c2ecf20Sopenharmony_ci 12848c2ecf20Sopenharmony_ciBesides running the "encrypt" group tests, for ext4 and f2fs it's also 12858c2ecf20Sopenharmony_cipossible to run most xfstests with the "test_dummy_encryption" mount 12868c2ecf20Sopenharmony_cioption. This option causes all new files to be automatically 12878c2ecf20Sopenharmony_ciencrypted with a dummy key, without having to make any API calls. 12888c2ecf20Sopenharmony_ciThis tests the encrypted I/O paths more thoroughly. To do this with 12898c2ecf20Sopenharmony_cikvm-xfstests, use the "encrypt" filesystem configuration:: 12908c2ecf20Sopenharmony_ci 12918c2ecf20Sopenharmony_ci kvm-xfstests -c ext4/encrypt,f2fs/encrypt -g auto 12928c2ecf20Sopenharmony_ci kvm-xfstests -c ext4/encrypt,f2fs/encrypt -g auto -m inlinecrypt 12938c2ecf20Sopenharmony_ci 12948c2ecf20Sopenharmony_ciBecause this runs many more tests than "-g encrypt" does, it takes 12958c2ecf20Sopenharmony_cimuch longer to run; so also consider using `gce-xfstests 12968c2ecf20Sopenharmony_ci<https://github.com/tytso/xfstests-bld/blob/master/Documentation/gce-xfstests.md>`_ 12978c2ecf20Sopenharmony_ciinstead of kvm-xfstests:: 12988c2ecf20Sopenharmony_ci 12998c2ecf20Sopenharmony_ci gce-xfstests -c ext4/encrypt,f2fs/encrypt -g auto 13008c2ecf20Sopenharmony_ci gce-xfstests -c ext4/encrypt,f2fs/encrypt -g auto -m inlinecrypt 1301