Skip to content

Commit 14f19dc

Browse files
committed
Merge tag 'fscrypt-for-linus' of git://git.kernel.org/pub/scm/fs/fscrypt/linux
Pull fscrypt update from Eric Biggers: "Add support for 'hardware-wrapped inline encryption keys' to fscrypt. When enabled on supported platforms, this feature protects file contents keys from certain attacks, such as cold boot attacks. This feature uses the block layer support for wrapped keys which was merged in 6.15. Wrapped key support has existed out-of-tree in Android for a long time, and it's finally ready for upstream now that there is a platform on which it works end-to-end with upstream. Specifically, it works on the Qualcomm SM8650 HDK, using the Qualcomm ICE (Inline Crypto Engine) and HWKM (Hardware Key Manager). The corresponding driver support is included in the SCSI tree for 6.16. Validation for this feature includes two new tests that were already merged into xfstests (generic/368 and generic/369)" * tag 'fscrypt-for-linus' of git://git.kernel.org/pub/scm/fs/fscrypt/linux: fscrypt: add support for hardware-wrapped keys
2 parents f83fcb8 + c07d3ae commit 14f19dc

File tree

8 files changed

+410
-105
lines changed

8 files changed

+410
-105
lines changed

Documentation/filesystems/fscrypt.rst

Lines changed: 149 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ Online attacks
7070
--------------
7171

7272
fscrypt (and storage encryption in general) can only provide limited
73-
protection, if any at all, against online attacks. In detail:
73+
protection against online attacks. In detail:
7474

7575
Side-channel attacks
7676
~~~~~~~~~~~~~~~~~~~~
@@ -99,16 +99,23 @@ Therefore, any encryption-specific access control checks would merely
9999
be enforced by kernel *code* and therefore would be largely redundant
100100
with the wide variety of access control mechanisms already available.)
101101

102-
Kernel memory compromise
103-
~~~~~~~~~~~~~~~~~~~~~~~~
102+
Read-only kernel memory compromise
103+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
104+
105+
Unless `hardware-wrapped keys`_ are used, an attacker who gains the
106+
ability to read from arbitrary kernel memory, e.g. by mounting a
107+
physical attack or by exploiting a kernel security vulnerability, can
108+
compromise all fscrypt keys that are currently in-use. This also
109+
extends to cold boot attacks; if the system is suddenly powered off,
110+
keys the system was using may remain in memory for a short time.
104111

105-
An attacker who compromises the system enough to read from arbitrary
106-
memory, e.g. by mounting a physical attack or by exploiting a kernel
107-
security vulnerability, can compromise all encryption keys that are
108-
currently in use.
112+
However, if hardware-wrapped keys are used, then the fscrypt master
113+
keys and file contents encryption keys (but not other types of fscrypt
114+
subkeys such as filenames encryption keys) are protected from
115+
compromises of arbitrary kernel memory.
109116

110-
However, fscrypt allows encryption keys to be removed from the kernel,
111-
which may protect them from later compromise.
117+
In addition, fscrypt allows encryption keys to be removed from the
118+
kernel, which may protect them from later compromise.
112119

113120
In more detail, the FS_IOC_REMOVE_ENCRYPTION_KEY ioctl (or the
114121
FS_IOC_REMOVE_ENCRYPTION_KEY_ALL_USERS ioctl) can wipe a master
@@ -144,6 +151,24 @@ However, these ioctls have some limitations:
144151
accelerator hardware (if used by the crypto API to implement any of
145152
the algorithms), or in other places not explicitly considered here.
146153

154+
Full system compromise
155+
~~~~~~~~~~~~~~~~~~~~~~
156+
157+
An attacker who gains "root" access and/or the ability to execute
158+
arbitrary kernel code can freely exfiltrate data that is protected by
159+
any in-use fscrypt keys. Thus, usually fscrypt provides no meaningful
160+
protection in this scenario. (Data that is protected by a key that is
161+
absent throughout the entire attack remains protected, modulo the
162+
limitations of key removal mentioned above in the case where the key
163+
was removed prior to the attack.)
164+
165+
However, if `hardware-wrapped keys`_ are used, such attackers will be
166+
unable to exfiltrate the master keys or file contents keys in a form
167+
that will be usable after the system is powered off. This may be
168+
useful if the attacker is significantly time-limited and/or
169+
bandwidth-limited, so they can only exfiltrate some data and need to
170+
rely on a later offline attack to exfiltrate the rest of it.
171+
147172
Limitations of v1 policies
148173
~~~~~~~~~~~~~~~~~~~~~~~~~~
149174

@@ -170,6 +195,10 @@ policies on all new encrypted directories.
170195
Key hierarchy
171196
=============
172197

198+
Note: this section assumes the use of raw keys rather than
199+
hardware-wrapped keys. The use of hardware-wrapped keys modifies the
200+
key hierarchy slightly. For details, see `Hardware-wrapped keys`_.
201+
173202
Master Keys
174203
-----------
175204

@@ -832,7 +861,9 @@ a pointer to struct fscrypt_add_key_arg, defined as follows::
832861
struct fscrypt_key_specifier key_spec;
833862
__u32 raw_size;
834863
__u32 key_id;
835-
__u32 __reserved[8];
864+
#define FSCRYPT_ADD_KEY_FLAG_HW_WRAPPED 0x00000001
865+
__u32 flags;
866+
__u32 __reserved[7];
836867
__u8 raw[];
837868
};
838869

@@ -851,7 +882,7 @@ a pointer to struct fscrypt_add_key_arg, defined as follows::
851882

852883
struct fscrypt_provisioning_key_payload {
853884
__u32 type;
854-
__u32 __reserved;
885+
__u32 flags;
855886
__u8 raw[];
856887
};
857888

@@ -879,24 +910,32 @@ as follows:
879910
Alternatively, if ``key_id`` is nonzero, this field must be 0, since
880911
in that case the size is implied by the specified Linux keyring key.
881912

882-
- ``key_id`` is 0 if the raw key is given directly in the ``raw``
883-
field. Otherwise ``key_id`` is the ID of a Linux keyring key of
884-
type "fscrypt-provisioning" whose payload is
885-
struct fscrypt_provisioning_key_payload whose ``raw`` field contains
886-
the raw key and whose ``type`` field matches ``key_spec.type``.
887-
Since ``raw`` is variable-length, the total size of this key's
888-
payload must be ``sizeof(struct fscrypt_provisioning_key_payload)``
889-
plus the raw key size. The process must have Search permission on
890-
this key.
891-
892-
Most users should leave this 0 and specify the raw key directly.
893-
The support for specifying a Linux keyring key is intended mainly to
913+
- ``key_id`` is 0 if the key is given directly in the ``raw`` field.
914+
Otherwise ``key_id`` is the ID of a Linux keyring key of type
915+
"fscrypt-provisioning" whose payload is struct
916+
fscrypt_provisioning_key_payload whose ``raw`` field contains the
917+
key, whose ``type`` field matches ``key_spec.type``, and whose
918+
``flags`` field matches ``flags``. Since ``raw`` is
919+
variable-length, the total size of this key's payload must be
920+
``sizeof(struct fscrypt_provisioning_key_payload)`` plus the number
921+
of key bytes. The process must have Search permission on this key.
922+
923+
Most users should leave this 0 and specify the key directly. The
924+
support for specifying a Linux keyring key is intended mainly to
894925
allow re-adding keys after a filesystem is unmounted and re-mounted,
895-
without having to store the raw keys in userspace memory.
926+
without having to store the keys in userspace memory.
927+
928+
- ``flags`` contains optional flags from ``<linux/fscrypt.h>``:
929+
930+
- FSCRYPT_ADD_KEY_FLAG_HW_WRAPPED: This denotes that the key is a
931+
hardware-wrapped key. See `Hardware-wrapped keys`_. This flag
932+
can't be used if FSCRYPT_KEY_SPEC_TYPE_DESCRIPTOR is used.
896933

897934
- ``raw`` is a variable-length field which must contain the actual
898935
key, ``raw_size`` bytes long. Alternatively, if ``key_id`` is
899-
nonzero, then this field is unused.
936+
nonzero, then this field is unused. Note that despite being named
937+
``raw``, if FSCRYPT_ADD_KEY_FLAG_HW_WRAPPED is specified then it
938+
will contain a wrapped key, not a raw key.
900939

901940
For v2 policy keys, the kernel keeps track of which user (identified
902941
by effective user ID) added the key, and only allows the key to be
@@ -908,8 +947,8 @@ prevent that other user from unexpectedly removing it. Therefore,
908947
FS_IOC_ADD_ENCRYPTION_KEY may also be used to add a v2 policy key
909948
*again*, even if it's already added by other user(s). In this case,
910949
FS_IOC_ADD_ENCRYPTION_KEY will just install a claim to the key for the
911-
current user, rather than actually add the key again (but the raw key
912-
must still be provided, as a proof of knowledge).
950+
current user, rather than actually add the key again (but the key must
951+
still be provided, as a proof of knowledge).
913952

914953
FS_IOC_ADD_ENCRYPTION_KEY returns 0 if either the key or a claim to
915954
the key was either added or already exists.
@@ -918,20 +957,23 @@ FS_IOC_ADD_ENCRYPTION_KEY can fail with the following errors:
918957

919958
- ``EACCES``: FSCRYPT_KEY_SPEC_TYPE_DESCRIPTOR was specified, but the
920959
caller does not have the CAP_SYS_ADMIN capability in the initial
921-
user namespace; or the raw key was specified by Linux key ID but the
960+
user namespace; or the key was specified by Linux key ID but the
922961
process lacks Search permission on the key.
962+
- ``EBADMSG``: invalid hardware-wrapped key
923963
- ``EDQUOT``: the key quota for this user would be exceeded by adding
924964
the key
925965
- ``EINVAL``: invalid key size or key specifier type, or reserved bits
926966
were set
927-
- ``EKEYREJECTED``: the raw key was specified by Linux key ID, but the
928-
key has the wrong type
929-
- ``ENOKEY``: the raw key was specified by Linux key ID, but no key
930-
exists with that ID
967+
- ``EKEYREJECTED``: the key was specified by Linux key ID, but the key
968+
has the wrong type
969+
- ``ENOKEY``: the key was specified by Linux key ID, but no key exists
970+
with that ID
931971
- ``ENOTTY``: this type of filesystem does not implement encryption
932972
- ``EOPNOTSUPP``: the kernel was not configured with encryption
933973
support for this filesystem, or the filesystem superblock has not
934-
had encryption enabled on it
974+
had encryption enabled on it; or a hardware wrapped key was specified
975+
but the filesystem does not support inline encryption or the hardware
976+
does not support hardware-wrapped keys
935977

936978
Legacy method
937979
~~~~~~~~~~~~~
@@ -994,9 +1036,8 @@ or removed by non-root users.
9941036
These ioctls don't work on keys that were added via the legacy
9951037
process-subscribed keyrings mechanism.
9961038

997-
Before using these ioctls, read the `Kernel memory compromise`_
998-
section for a discussion of the security goals and limitations of
999-
these ioctls.
1039+
Before using these ioctls, read the `Online attacks`_ section for a
1040+
discussion of the security goals and limitations of these ioctls.
10001041

10011042
FS_IOC_REMOVE_ENCRYPTION_KEY
10021043
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -1316,15 +1357,85 @@ inline encryption hardware doesn't have the needed crypto capabilities
13161357
(e.g. support for the needed encryption algorithm and data unit size)
13171358
and where blk-crypto-fallback is unusable. (For blk-crypto-fallback
13181359
to be usable, it must be enabled in the kernel configuration with
1319-
CONFIG_BLK_INLINE_ENCRYPTION_FALLBACK=y.)
1360+
CONFIG_BLK_INLINE_ENCRYPTION_FALLBACK=y, and the file must be
1361+
protected by a raw key rather than a hardware-wrapped key.)
13201362

13211363
Currently fscrypt always uses the filesystem block size (which is
13221364
usually 4096 bytes) as the data unit size. Therefore, it can only use
13231365
inline encryption hardware that supports that data unit size.
13241366

13251367
Inline encryption doesn't affect the ciphertext or other aspects of
13261368
the on-disk format, so users may freely switch back and forth between
1327-
using "inlinecrypt" and not using "inlinecrypt".
1369+
using "inlinecrypt" and not using "inlinecrypt". An exception is that
1370+
files that are protected by a hardware-wrapped key can only be
1371+
encrypted/decrypted by the inline encryption hardware and therefore
1372+
can only be accessed when the "inlinecrypt" mount option is used. For
1373+
more information about hardware-wrapped keys, see below.
1374+
1375+
Hardware-wrapped keys
1376+
---------------------
1377+
1378+
fscrypt supports using *hardware-wrapped keys* when the inline
1379+
encryption hardware supports it. Such keys are only present in kernel
1380+
memory in wrapped (encrypted) form; they can only be unwrapped
1381+
(decrypted) by the inline encryption hardware and are temporally bound
1382+
to the current boot. This prevents the keys from being compromised if
1383+
kernel memory is leaked. This is done without limiting the number of
1384+
keys that can be used and while still allowing the execution of
1385+
cryptographic tasks that are tied to the same key but can't use inline
1386+
encryption hardware, e.g. filenames encryption.
1387+
1388+
Note that hardware-wrapped keys aren't specific to fscrypt; they are a
1389+
block layer feature (part of *blk-crypto*). For more details about
1390+
hardware-wrapped keys, see the block layer documentation at
1391+
:ref:`Documentation/block/inline-encryption.rst
1392+
<hardware_wrapped_keys>`. The rest of this section just focuses on
1393+
the details of how fscrypt can use hardware-wrapped keys.
1394+
1395+
fscrypt supports hardware-wrapped keys by allowing the fscrypt master
1396+
keys to be hardware-wrapped keys as an alternative to raw keys. To
1397+
add a hardware-wrapped key with `FS_IOC_ADD_ENCRYPTION_KEY`_,
1398+
userspace must specify FSCRYPT_ADD_KEY_FLAG_HW_WRAPPED in the
1399+
``flags`` field of struct fscrypt_add_key_arg and also in the
1400+
``flags`` field of struct fscrypt_provisioning_key_payload when
1401+
applicable. The key must be in ephemerally-wrapped form, not
1402+
long-term wrapped form.
1403+
1404+
Some limitations apply. First, files protected by a hardware-wrapped
1405+
key are tied to the system's inline encryption hardware. Therefore
1406+
they can only be accessed when the "inlinecrypt" mount option is used,
1407+
and they can't be included in portable filesystem images. Second,
1408+
currently the hardware-wrapped key support is only compatible with
1409+
`IV_INO_LBLK_64 policies`_ and `IV_INO_LBLK_32 policies`_, as it
1410+
assumes that there is just one file contents encryption key per
1411+
fscrypt master key rather than one per file. Future work may address
1412+
this limitation by passing per-file nonces down the storage stack to
1413+
allow the hardware to derive per-file keys.
1414+
1415+
Implementation-wise, to encrypt/decrypt the contents of files that are
1416+
protected by a hardware-wrapped key, fscrypt uses blk-crypto,
1417+
attaching the hardware-wrapped key to the bio crypt contexts. As is
1418+
the case with raw keys, the block layer will program the key into a
1419+
keyslot when it isn't already in one. However, when programming a
1420+
hardware-wrapped key, the hardware doesn't program the given key
1421+
directly into a keyslot but rather unwraps it (using the hardware's
1422+
ephemeral wrapping key) and derives the inline encryption key from it.
1423+
The inline encryption key is the key that actually gets programmed
1424+
into a keyslot, and it is never exposed to software.
1425+
1426+
However, fscrypt doesn't just do file contents encryption; it also
1427+
uses its master keys to derive filenames encryption keys, key
1428+
identifiers, and sometimes some more obscure types of subkeys such as
1429+
dirhash keys. So even with file contents encryption out of the
1430+
picture, fscrypt still needs a raw key to work with. To get such a
1431+
key from a hardware-wrapped key, fscrypt asks the inline encryption
1432+
hardware to derive a cryptographically isolated "software secret" from
1433+
the hardware-wrapped key. fscrypt uses this "software secret" to key
1434+
its KDF to derive all subkeys other than file contents keys.
1435+
1436+
Note that this implies that the hardware-wrapped key feature only
1437+
protects the file contents encryption keys. It doesn't protect other
1438+
fscrypt subkeys such as filenames encryption keys.
13281439

13291440
Direct I/O support
13301441
==================

0 commit comments

Comments
 (0)