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