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