From: Ahmad Fatoum <a.fatoum@pengutronix.de>
To: "Theodore Y. Ts'o" <tytso@mit.edu>,
Jaegeuk Kim <jaegeuk@kernel.org>,
Eric Biggers <ebiggers@kernel.org>
Cc: kernel@pengutronix.de, Ahmad Fatoum <a.fatoum@pengutronix.de>,
Jarkko Sakkinen <jarkko@kernel.org>,
James Morris <jmorris@namei.org>,
"Serge E. Hallyn" <serge@hallyn.com>,
James Bottomley <jejb@linux.ibm.com>,
Mimi Zohar <zohar@linux.ibm.com>,
Sumit Garg <sumit.garg@linaro.org>,
David Howells <dhowells@redhat.com>,
linux-fscrypt@vger.kernel.org, linux-crypto@vger.kernel.org,
linux-integrity@vger.kernel.org,
linux-security-module@vger.kernel.org, keyrings@vger.kernel.org,
linux-kernel@vger.kernel.org
Subject: [PATCH v2] fscrypt: support trusted keys
Date: Fri, 6 Aug 2021 17:09:28 +0200 [thread overview]
Message-ID: <20210806150928.27857-1-a.fatoum@pengutronix.de> (raw)
Kernel trusted keys don't require userspace knowledge of the raw key
material and instead export a sealed blob, which can be persisted to
unencrypted storage. Userspace can then load this blob into the kernel,
where it's unsealed and from there on usable for kernel crypto.
This is incompatible with fscrypt, where userspace is supposed to supply
the raw key material. For TPMs, a work around is to do key unsealing in
userspace, but this may not be feasible for other trusted key backends.
Make it possible to benefit from both fscrypt and trusted key sealing
by extending fscrypt_add_key_arg::key_id to hold either the ID of a
fscrypt-provisioning or a trusted key.
A non fscrypt-provisioning key_id was so far prohibited, so additionally
allowing trusted keys won't break backwards compatibility.
Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
---
Tested with:
https://github.com/google/fscryptctl/pull/23
v1 here:
https://lore.kernel.org/linux-fscrypt/20210727144349.11215-1-a.fatoum@pengutronix.de/T/#u
v1 -> v2:
- Drop encrypted key support and key_extract_material
- Use key_id instead of repurposing raw (Eric)
- Shift focus to trusted key sealing for non-TPM as a rationale
why this integration is worthwhile (Eric)
- Extend documentation with rationale on why one would
use trusted keys and warn about trusted key reuse
To: "Theodore Y. Ts'o" <tytso@mit.edu>
To: Jaegeuk Kim <jaegeuk@kernel.org>
To: Eric Biggers <ebiggers@kernel.org>
Cc: Jarkko Sakkinen <jarkko@kernel.org>
Cc: James Morris <jmorris@namei.org>
Cc: "Serge E. Hallyn" <serge@hallyn.com>
Cc: James Bottomley <jejb@linux.ibm.com>
Cc: Mimi Zohar <zohar@linux.ibm.com>
Cc: Sumit Garg <sumit.garg@linaro.org>
Cc: David Howells <dhowells@redhat.com>
Cc: linux-fscrypt@vger.kernel.org
Cc: linux-crypto@vger.kernel.org
Cc: linux-integrity@vger.kernel.org
Cc: linux-security-module@vger.kernel.org
Cc: keyrings@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
---
Documentation/filesystems/fscrypt.rst | 31 ++++++++++++++-----
fs/crypto/keyring.c | 43 +++++++++++++++++++--------
2 files changed, 54 insertions(+), 20 deletions(-)
diff --git a/Documentation/filesystems/fscrypt.rst b/Documentation/filesystems/fscrypt.rst
index 44b67ebd6e40..c1811fa4285a 100644
--- a/Documentation/filesystems/fscrypt.rst
+++ b/Documentation/filesystems/fscrypt.rst
@@ -734,23 +734,40 @@ as follows:
- ``key_id`` is 0 if the raw key is given directly in the ``raw``
field. Otherwise ``key_id`` is the ID of a Linux keyring key of
- type "fscrypt-provisioning" whose payload is
+ type "fscrypt-provisioning" or "trusted":
+ "fscrypt-provisioning" keys have a payload of
struct fscrypt_provisioning_key_payload whose ``raw`` field contains
the raw key and whose ``type`` field matches ``key_spec.type``.
Since ``raw`` is variable-length, the total size of this key's
payload must be ``sizeof(struct fscrypt_provisioning_key_payload)``
- plus the raw key size. The process must have Search permission on
- this key.
-
- Most users should leave this 0 and specify the raw key directly.
- The support for specifying a Linux keyring key is intended mainly to
- allow re-adding keys after a filesystem is unmounted and re-mounted,
+ plus the raw key size.
+ For "trusted" keys, the payload is directly taken as the raw key.
+
+ The process must have Search permission on this key.
+
+ Most users leave this 0 and specify the raw key directly.
+ "trusted" keys are useful to leverage kernel support for sealing
+ and unsealing key material. Sealed keys can be persisted to
+ unencrypted storage and later be used to decrypt the file system
+ without requiring userspace to have knowledge of the raw key
+ material.
+ "fscrypt-provisioning" key support is intended mainly to allow
+ re-adding keys after a filesystem is unmounted and re-mounted,
without having to store the raw keys in userspace memory.
- ``raw`` is a variable-length field which must contain the actual
key, ``raw_size`` bytes long. Alternatively, if ``key_id`` is
nonzero, then this field is unused.
+.. note::
+
+ Users should take care not to reuse the fscrypt key material with
+ different ciphers or in multiple contexts as this may make it
+ easier to deduce the key.
+ This also applies when the key material is supplied indirectly
+ via a kernel trusted key. In this case, the trusted key should
+ perferably be used only in a single context.
+
For v2 policy keys, the kernel keeps track of which user (identified
by effective user ID) added the key, and only allows the key to be
removed by that user --- or by "root", if they use
diff --git a/fs/crypto/keyring.c b/fs/crypto/keyring.c
index 0b3ffbb4faf4..721f5da51416 100644
--- a/fs/crypto/keyring.c
+++ b/fs/crypto/keyring.c
@@ -20,6 +20,7 @@
#include <crypto/skcipher.h>
#include <linux/key-type.h>
+#include <keys/trusted-type.h>
#include <linux/random.h>
#include <linux/seq_file.h>
@@ -577,28 +578,44 @@ static int get_keyring_key(u32 key_id, u32 type,
key_ref_t ref;
struct key *key;
const struct fscrypt_provisioning_key_payload *payload;
- int err;
+ int err = 0;
ref = lookup_user_key(key_id, 0, KEY_NEED_SEARCH);
if (IS_ERR(ref))
return PTR_ERR(ref);
key = key_ref_to_ptr(ref);
- if (key->type != &key_type_fscrypt_provisioning)
- goto bad_key;
- payload = key->payload.data[0];
+ if (key->type == &key_type_fscrypt_provisioning) {
+ payload = key->payload.data[0];
- /* Don't allow fscrypt v1 keys to be used as v2 keys and vice versa. */
- if (payload->type != type)
- goto bad_key;
+ /* Don't allow fscrypt v1 keys to be used as v2 keys and vice versa. */
+ if (payload->type != type) {
+ err = -EKEYREJECTED;
+ goto out_put;
+ }
- secret->size = key->datalen - sizeof(*payload);
- memcpy(secret->raw, payload->raw, secret->size);
- err = 0;
- goto out_put;
+ secret->size = key->datalen - sizeof(*payload);
+ memcpy(secret->raw, payload->raw, secret->size);
+ } else if (IS_REACHABLE(CONFIG_TRUSTED_KEYS) && key->type == &key_type_trusted) {
+ struct trusted_key_payload *tkp;
+
+ /* avoid reseal changing payload while we memcpy key */
+ down_read(&key->sem);
+ tkp = key->payload.data[0];
+ if (!tkp || tkp->key_len < FSCRYPT_MIN_KEY_SIZE ||
+ tkp->key_len > FSCRYPT_MAX_KEY_SIZE) {
+ up_read(&key->sem);
+ err = -EINVAL;
+ goto out_put;
+ }
+
+ secret->size = tkp->key_len;
+ memcpy(secret->raw, tkp->key, secret->size);
+ up_read(&key->sem);
+ } else {
+ err = -EKEYREJECTED;
+ }
-bad_key:
- err = -EKEYREJECTED;
out_put:
key_ref_put(ref);
return err;
--
2.30.2
next reply other threads:[~2021-08-06 15:09 UTC|newest]
Thread overview: 23+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-08-06 15:09 Ahmad Fatoum [this message]
2021-08-09 9:44 ` [PATCH v2] fscrypt: support trusted keys Jarkko Sakkinen
2021-08-09 10:00 ` Ahmad Fatoum
2021-08-09 10:02 ` Ahmad Fatoum
2021-08-10 18:02 ` Jarkko Sakkinen
2021-08-09 20:52 ` Eric Biggers
2021-08-10 18:06 ` Jarkko Sakkinen
2021-08-10 18:46 ` Eric Biggers
2021-08-10 21:21 ` Jarkko Sakkinen
2021-08-10 21:27 ` Eric Biggers
2021-08-11 0:17 ` Jarkko Sakkinen
2021-08-11 11:34 ` Mimi Zohar
2021-08-11 17:16 ` Eric Biggers
2021-08-12 0:54 ` Mimi Zohar
2021-08-17 13:04 ` Ahmad Fatoum
2021-08-17 13:55 ` Mimi Zohar
2021-08-17 14:13 ` Ahmad Fatoum
2021-08-17 14:24 ` Mimi Zohar
2021-08-18 2:09 ` Jarkko Sakkinen
2021-08-18 4:53 ` Sumit Garg
2021-08-09 21:24 ` Eric Biggers
2021-08-10 7:41 ` Ahmad Fatoum
2021-08-10 17:35 ` Eric Biggers
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20210806150928.27857-1-a.fatoum@pengutronix.de \
--to=a.fatoum@pengutronix.de \
--cc=dhowells@redhat.com \
--cc=ebiggers@kernel.org \
--cc=jaegeuk@kernel.org \
--cc=jarkko@kernel.org \
--cc=jejb@linux.ibm.com \
--cc=jmorris@namei.org \
--cc=kernel@pengutronix.de \
--cc=keyrings@vger.kernel.org \
--cc=linux-crypto@vger.kernel.org \
--cc=linux-fscrypt@vger.kernel.org \
--cc=linux-integrity@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-security-module@vger.kernel.org \
--cc=serge@hallyn.com \
--cc=sumit.garg@linaro.org \
--cc=tytso@mit.edu \
--cc=zohar@linux.ibm.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.