diff options
Diffstat (limited to 'Documentation/filesystems/fscrypt.rst')
| -rw-r--r-- | Documentation/filesystems/fscrypt.rst | 158 |
1 files changed, 83 insertions, 75 deletions
diff --git a/Documentation/filesystems/fscrypt.rst b/Documentation/filesystems/fscrypt.rst index c0dd35f1af12..6e2e511a70bb 100644 --- a/Documentation/filesystems/fscrypt.rst +++ b/Documentation/filesystems/fscrypt.rst @@ -188,8 +188,8 @@ attacks: - Non-root users cannot securely remove encryption keys. All the above problems are fixed with v2 encryption policies. For -this reason among others, it is recommended to use v2 encryption -policies on all new encrypted directories. +this reason among others, v1 encryption policies are deprecated. Use +v2 encryption policies on all new encrypted directories. Key hierarchy ============= @@ -305,7 +305,8 @@ included in the IV. Moreover: - For v2 encryption policies, the encryption is done with a per-mode key derived using the KDF. Users may use the same master key for - other v2 encryption policies. + other v2 encryption policies. However, using a distinct master key + for each policy is still the best practice and normal usage. IV_INO_LBLK_64 policies ----------------------- @@ -336,6 +337,9 @@ per I/O request and may have only a small number of keyslots. This format results in some level of IV reuse, so it should only be used when necessary due to hardware limitations. +IV_INO_LBLK_32 is supported only when the filesystem block size is +equal to the page size. + Key identifiers --------------- @@ -601,7 +605,9 @@ This structure must be initialized as follows: struct fscrypt_policy_v1 is used or FSCRYPT_POLICY_V2 (2) if struct fscrypt_policy_v2 is used. (Note: we refer to the original policy version as "v1", though its version code is really 0.) - For new encrypted directories, use v2 policies. + For new encrypted directories, use v2 policies, which are supported + since Linux v5.4. v1 policies are deprecated and have several + usability and security problems. - ``contents_encryption_mode`` and ``filenames_encryption_mode`` must be set to constants from ``<linux/fscrypt.h>`` which identify the @@ -736,17 +742,6 @@ FS_IOC_SET_ENCRYPTION_POLICY can fail with the following errors: Getting an encryption policy ---------------------------- -Two ioctls are available to get a file's encryption policy: - -- `FS_IOC_GET_ENCRYPTION_POLICY_EX`_ -- `FS_IOC_GET_ENCRYPTION_POLICY`_ - -The extended (_EX) version of the ioctl is more general and is -recommended to use when possible. However, on older kernels only the -original ioctl is available. Applications should try the extended -version, and if it fails with ENOTTY fall back to the original -version. - FS_IOC_GET_ENCRYPTION_POLICY_EX ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -780,7 +775,6 @@ FS_IOC_GET_ENCRYPTION_POLICY_EX can fail with the following errors: - ``ENODATA``: the file is not encrypted - ``ENOTTY``: this type of filesystem does not implement encryption, or this kernel is too old to support FS_IOC_GET_ENCRYPTION_POLICY_EX - (try FS_IOC_GET_ENCRYPTION_POLICY instead) - ``EOPNOTSUPP``: the kernel was not configured with encryption support for this filesystem, or the filesystem superblock has not had encryption enabled on it @@ -796,12 +790,13 @@ check for STATX_ATTR_ENCRYPTED in stx_attributes. FS_IOC_GET_ENCRYPTION_POLICY ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -The FS_IOC_GET_ENCRYPTION_POLICY ioctl can also retrieve the -encryption policy, if any, for a directory or regular file. However, -unlike `FS_IOC_GET_ENCRYPTION_POLICY_EX`_, -FS_IOC_GET_ENCRYPTION_POLICY only supports the original policy -version. It takes in a pointer directly to struct fscrypt_policy_v1 -rather than struct fscrypt_get_policy_ex_arg. +The FS_IOC_GET_ENCRYPTION_POLICY ioctl is deprecated. It supports +only v1 encryption policies, which themselves are deprecated. Use +`FS_IOC_GET_ENCRYPTION_POLICY_EX`_ instead. + +FS_IOC_GET_ENCRYPTION_POLICY retrieves the encryption policy for a +directory or regular file, but only if it uses a v1 policy. It takes +in a pointer directly to struct fscrypt_policy_v1. The error codes for FS_IOC_GET_ENCRYPTION_POLICY are the same as those for FS_IOC_GET_ENCRYPTION_POLICY_EX, except that @@ -884,6 +879,10 @@ as follows: To add this type of key, the calling process must have the CAP_SYS_ADMIN capability in the initial user namespace. + (Note that v1 encryption policies are deprecated. The ability to + add a key for v1 encryption policies remains only for compatibility + with existing encrypted directories.) + Alternatively, if the key is being added for use by v2 encryption policies, then ``key_spec.type`` must contain FSCRYPT_KEY_SPEC_TYPE_IDENTIFIER, and ``key_spec.u.identifier`` is @@ -1238,6 +1237,10 @@ astute users may notice some differences in behavior: - DAX (Direct Access) is not supported on encrypted files. +- Encrypted files cannot be used directly as swap files. To swap to + an encrypted file, set up a loopback device on top of it. + Alternatively, encrypted swap can use a dm-crypt device. + - The maximum length of an encrypted symlink is 2 bytes shorter than the maximum length of an unencrypted symlink. For example, on an EXT4 filesystem with a 4K block size, unencrypted symlinks can be up @@ -1315,32 +1318,20 @@ Inline encryption support Many newer systems (especially mobile SoCs) have *inline encryption hardware* that can encrypt/decrypt data while it is on its way to/from -the storage device. Linux supports inline encryption through a set of -extensions to the block layer called *blk-crypto*. blk-crypto allows -filesystems to attach encryption contexts to bios (I/O requests) to -specify how the data will be encrypted or decrypted in-line. For more -information about blk-crypto, see -:ref:`Documentation/block/inline-encryption.rst <inline_encryption>`. +the storage device. On supported filesystems (currently ext4 and f2fs), fscrypt can use -blk-crypto instead of the kernel crypto API to encrypt/decrypt file -contents. To enable this, set CONFIG_FS_ENCRYPTION_INLINE_CRYPT=y in -the kernel configuration, and specify the "inlinecrypt" mount option -when mounting the filesystem. - -Note that the "inlinecrypt" mount option just specifies to use inline -encryption when possible; it doesn't force its use. fscrypt will -still fall back to using the kernel crypto API on files where the -inline encryption hardware doesn't have the needed crypto capabilities -(e.g. support for the needed encryption algorithm and data unit size) -and where blk-crypto-fallback is unusable. (For blk-crypto-fallback -to be usable, it must be enabled in the kernel configuration with -CONFIG_BLK_INLINE_ENCRYPTION_FALLBACK=y, and the file must be -protected by a raw key rather than a hardware-wrapped key.) - -Currently fscrypt always uses the filesystem block size (which is -usually 4096 bytes) as the data unit size. Therefore, it can only use -inline encryption hardware that supports that data unit size. +inline encryption hardware instead of the CPU to encrypt/decrypt file +contents. To enable this, specify the "inlinecrypt" mount option when +mounting the filesystem. + +This causes the filesystem to use inline encryption hardware whenever +possible, falling back to the CPU only if such hardware is absent or +doesn't provide the needed crypto capabilities. + +For more information about the kernel's support for inline encryption +hardware, see :ref:`Documentation/block/inline-encryption.rst +<inline_encryption>`. Inline encryption doesn't affect the ciphertext or other aspects of the on-disk format, so users may freely switch back and forth between @@ -1422,10 +1413,8 @@ For direct I/O on an encrypted file to work, the following conditions must be met (in addition to the conditions for direct I/O on an unencrypted file): -* The file must be using inline encryption. Usually this means that - the filesystem must be mounted with ``-o inlinecrypt`` and inline - encryption hardware must be present. However, a software fallback - is also available. For details, see `Inline encryption support`_. +* The filesystem must be block-based. (Before Linux v7.3, the + filesystem also needed to be mounted with ``-o inlinecrypt``.) * The I/O request must be fully aligned to the filesystem block size. This means that the file position the I/O is targeting, the lengths @@ -1486,25 +1475,43 @@ keys`_ and `DIRECT_KEY policies`_. Data path changes ----------------- -When inline encryption is used, filesystems just need to associate -encryption contexts with bios to specify how the block layer or the -inline encryption hardware will encrypt/decrypt the file contents. - -When inline encryption isn't used, filesystems must encrypt/decrypt -the file contents themselves, as described below: - -For the read path (->read_folio()) of regular files, filesystems can -read the ciphertext into the page cache and decrypt it in-place. The -folio lock must be held until decryption has finished, to prevent the -folio from becoming visible to userspace prematurely. - -For the write path (->writepages()) of regular files, filesystems -cannot encrypt data in-place in the page cache, since the cached -plaintext must be preserved. Instead, filesystems must encrypt into a -temporary buffer or "bounce page", then write out the temporary -buffer. Some filesystems, such as UBIFS, already use temporary -buffers regardless of encryption. Other filesystems, such as ext4 and -F2FS, have to allocate bounce pages specially for encryption. +The block-based filesystems that support fscrypt, such as ext4 and +f2fs, use blk-crypto (:ref:`inline_encryption`) to implement file +contents encryption and decryption. With blk-crypto, the filesystem +assigns an encryption context to each I/O request it issues to the +contents of an encrypted file. The encryption (for writes) or +decryption (for reads) is handled by the block layer transparently to +the filesystem, using either the CPU or inline encryption hardware. + +Non-block-based filesystems can't use blk-crypto, so they make the +calls to the cryptographic algorithms at the filesystem layer instead. + +Regardless of the layer in which they occur (blk-crypto-fallback or the +filesystem), for CPU-based encryption and decryption of file contents: + +- For reads, the ciphertext data is read from the storage backend + (block device, network, UBI device, etc.) into the destination + buffers, then decrypted in-place. The destination buffers are + pagecache folios for buffered reads, or application-provided buffers + for direct reads. In either case, the filesystem reports success + only after decryption has successfully completed. + +- For writes, the plaintext data is encrypted from the source buffers + (which cannot be modified) into bounce buffers. Then, the + ciphertext in the bounce buffers is written to the storage backend. + + The source buffers are usually pagecache folios for buffered writes, + or application-provided buffers for direct writes. There are also + some cases (all files on UBIFS, and compressed files on f2fs) where + the filesystem already uses bounce buffers for writes for other + reasons; in these cases the source plaintext data is already in + bounce buffers. UBIFS optimizes this case by encrypting the data + in-place in its existing bounce buffers. + +When inline encryption hardware is used instead of the CPU, reads from +the storage backend logically return plaintext data, and writes accept +plaintext data. In that case the flow is simplified: there's no +scheduling of decryption work, and no bounce buffers are used. Filename hashing and encoding ----------------------------- @@ -1552,14 +1559,11 @@ Tests To test fscrypt, use xfstests, which is Linux's de facto standard filesystem test suite. First, run all the tests in the "encrypt" -group on the relevant filesystem(s). One can also run the tests -with the 'inlinecrypt' mount option to test the implementation for -inline encryption support. For example, to test ext4 and +group on the relevant filesystem(s). For example, to test ext4 and f2fs encryption using `kvm-xfstests <https://github.com/tytso/xfstests-bld/blob/master/Documentation/kvm-quickstart.md>`_:: kvm-xfstests -c ext4,f2fs -g encrypt - kvm-xfstests -c ext4,f2fs -g encrypt -m inlinecrypt UBIFS encryption can also be tested this way, but it should be done in a separate command, and it takes some time for kvm-xfstests to set up @@ -1581,7 +1585,6 @@ This tests the encrypted I/O paths more thoroughly. To do this with kvm-xfstests, use the "encrypt" filesystem configuration:: kvm-xfstests -c ext4/encrypt,f2fs/encrypt -g auto - kvm-xfstests -c ext4/encrypt,f2fs/encrypt -g auto -m inlinecrypt Because this runs many more tests than "-g encrypt" does, it takes much longer to run; so also consider using `gce-xfstests @@ -1589,4 +1592,9 @@ much longer to run; so also consider using `gce-xfstests instead of kvm-xfstests:: gce-xfstests -c ext4/encrypt,f2fs/encrypt -g auto - gce-xfstests -c ext4/encrypt,f2fs/encrypt -g auto -m inlinecrypt + +To test inline encryption hardware on a platform that supports such +hardware, run xfstests directly with the ``inlinecrypt`` mount option +enabled. For example:: + + EXT_MOUNT_OPTIONS="-o inlinecrypt" ./check -g encrypt |
