Linux-FSCrypt Archive mirror
 help / color / mirror / Atom feed
From: Sweet Tea Dorminy <sweettea-kernel@dorminy.me>
To: ebiggers@kernel.org, tytso@mit.edu, jaegeuk@kernel.org,
	linux-fscrypt@vger.kernel.org, kernel-team@meta.com
Cc: Sweet Tea Dorminy <sweettea-kernel@dorminy.me>
Subject: [PATCH v1 08/10] fscrypt: make prepared keys record their type.
Date: Mon, 10 Apr 2023 06:16:29 -0400	[thread overview]
Message-ID: <c821c5e73252b47a57ccc80d805a86510462f005.1681116740.git.sweettea-kernel@dorminy.me> (raw)
In-Reply-To: <cover.1681116739.git.sweettea-kernel@dorminy.me>

Right now fscrypt_infos have two fields dedicated solely to recording
what type of prepared key the info has: whether it solely owns the
prepared key, or has borrowed it from a master key, or from a direct
key.

This information doesn't change during the lifetime of a prepared key.
Since at worst there's a prepared key per info, and at best many infos
share a single prepared key, it is slightly more efficient to store this
ownership info in the prepared key instead of in the fscrypt_info.
Especially since we can squash both fields down into a single enum. This
will also make it easy to record that a prepared key is part of the
pooled prepared keys when extent-based encryption is used.

Signed-off-by: Sweet Tea Dorminy <sweettea-kernel@dorminy.me>
---
 fs/crypto/fscrypt_private.h | 28 ++++++++++++++++++++++------
 fs/crypto/keysetup.c        | 19 ++++++++++++-------
 fs/crypto/keysetup_v1.c     |  2 +-
 3 files changed, 35 insertions(+), 14 deletions(-)

diff --git a/fs/crypto/fscrypt_private.h b/fs/crypto/fscrypt_private.h
index b575fb58a506..e726a1fb9f7e 100644
--- a/fs/crypto/fscrypt_private.h
+++ b/fs/crypto/fscrypt_private.h
@@ -174,18 +174,39 @@ struct fscrypt_symlink_data {
 	char encrypted_path[1];
 } __packed;
 
+/**
+ * enum fscrypt_prepared_key_type - records a prepared key's ownership
+ *
+ * @FSCRYPT_KEY_PER_INFO: this prepared key is allocated for a specific info
+ *		          and is never shared.
+ * @FSCRYPT_KEY_DIRECT_V1: this prepared key is embedded in a fscrypt_direct_key
+ *		           used in v1 direct key policies.
+ * @FSCRYPT_KEY_MASTER_KEY: this prepared key is a per-mode and policy key,
+ *			    part of a fscrypt_master_key, shared between all
+ *			    users of this master key having this mode and
+ *			    policy.
+ */
+enum fscrypt_prepared_key_type {
+	FSCRYPT_KEY_PER_INFO = 1,
+	FSCRYPT_KEY_DIRECT_V1,
+	FSCRYPT_KEY_MASTER_KEY,
+} __packed;
+
 /**
  * struct fscrypt_prepared_key - a key prepared for actual encryption/decryption
  * @tfm: crypto API transform object
  * @blk_key: key for blk-crypto
+ * @type: records the ownership type of the prepared key
  *
- * Normally only one of the fields will be non-NULL.
+ * Normally only one of @tfm and @blk_key will be non-NULL, although it is
+ * possible if @type is FSCRYPT_KEY_MASTER_KEY.
  */
 struct fscrypt_prepared_key {
 	struct crypto_skcipher *tfm;
 #ifdef CONFIG_FS_ENCRYPTION_INLINE_CRYPT
 	struct blk_crypto_key *blk_key;
 #endif
+	enum fscrypt_prepared_key_type type;
 };
 
 /*
@@ -233,11 +254,6 @@ struct fscrypt_info {
 	 */
 	struct list_head ci_master_key_link;
 
-	/*
-	 * If true, then encryption is done using the master key directly.
-	 */
-	bool ci_direct_key;
-
 	/*
 	 * This inode's hash key for filenames.  This is a 128-bit SipHash-2-4
 	 * key.  This is only set for directories that use a keyed dirhash over
diff --git a/fs/crypto/keysetup.c b/fs/crypto/keysetup.c
index d81001bf0a51..f338bb544932 100644
--- a/fs/crypto/keysetup.c
+++ b/fs/crypto/keysetup.c
@@ -185,11 +185,11 @@ void fscrypt_destroy_prepared_key(struct super_block *sb,
 /* Given a per-file encryption key, set up the file's crypto transform object */
 int fscrypt_set_per_file_enc_key(struct fscrypt_info *ci, const u8 *raw_key)
 {
-	ci->ci_owns_key = true;
 	ci->ci_enc_key = kzalloc(sizeof(*ci->ci_enc_key), GFP_KERNEL);
 	if (!ci->ci_enc_key)
 		return -ENOMEM;
 
+	ci->ci_enc_key->type = FSCRYPT_KEY_PER_INFO;
 	return fscrypt_prepare_key(ci->ci_enc_key, raw_key, ci);
 }
 
@@ -284,6 +284,7 @@ static int setup_new_mode_prepared_key(struct fscrypt_master_key *mk,
 				  mode_key, mode->keysize);
 	if (err)
 		goto out_unlock;
+	prep_key->type = FSCRYPT_KEY_MASTER_KEY;
 	err = fscrypt_prepare_key(prep_key, mode_key, ci);
 	memzero_explicit(mode_key, mode->keysize);
 	if (err)
@@ -577,12 +578,16 @@ static void put_crypt_info(struct fscrypt_info *ci)
 	if (!ci)
 		return;
 
-	if (ci->ci_direct_key)
-		fscrypt_put_direct_key(ci->ci_enc_key);
-	else if (ci->ci_owns_key) {
-		fscrypt_destroy_prepared_key(ci->ci_inode->i_sb,
-					     ci->ci_enc_key);
-		kfree(ci->ci_enc_key);
+	if (ci->ci_enc_key) {
+		enum fscrypt_prepared_key_type type = ci->ci_enc_key->type;
+
+		if (type == FSCRYPT_KEY_DIRECT_V1)
+			fscrypt_put_direct_key(ci->ci_enc_key);
+		if (type == FSCRYPT_KEY_PER_INFO) {
+			fscrypt_destroy_prepared_key(ci->ci_inode->i_sb,
+						     ci->ci_enc_key);
+			kfree(ci->ci_enc_key);
+		}
 	}
 
 	mk = ci->ci_master_key;
diff --git a/fs/crypto/keysetup_v1.c b/fs/crypto/keysetup_v1.c
index 09de84c65368..1e785cedead0 100644
--- a/fs/crypto/keysetup_v1.c
+++ b/fs/crypto/keysetup_v1.c
@@ -238,6 +238,7 @@ fscrypt_get_direct_key(const struct fscrypt_info *ci, const u8 *raw_key)
 	dk->dk_sb = ci->ci_inode->i_sb;
 	refcount_set(&dk->dk_refcount, 1);
 	dk->dk_mode = ci->ci_mode;
+	dk->dk_key.type = FSCRYPT_KEY_DIRECT_V1;
 	err = fscrypt_prepare_key(&dk->dk_key, raw_key, ci);
 	if (err)
 		goto err_free_dk;
@@ -261,7 +262,6 @@ static int setup_v1_file_key_direct(struct fscrypt_info *ci,
 	dk = fscrypt_get_direct_key(ci, raw_master_key);
 	if (IS_ERR(dk))
 		return PTR_ERR(dk);
-	ci->ci_direct_key = true;
 	ci->ci_enc_key = &dk->dk_key;
 	return 0;
 }
-- 
2.40.0


  parent reply	other threads:[~2023-04-10 10:26 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-04-10 10:16 [PATCH v1 00/10] fscrypt: rearrangements preliminary to extent encryption Sweet Tea Dorminy
2023-04-10 10:16 ` [PATCH v1 01/10] fscrypt: split and rename setup_file_encryption_key() Sweet Tea Dorminy
2023-04-10 10:16 ` [PATCH v1 02/10] fscrypt: split and rename setup_per_mode_enc_key() Sweet Tea Dorminy
2023-04-10 10:16 ` [PATCH v1 03/10] fscrypt: move dirhash key setup away from IO key setup Sweet Tea Dorminy
2023-04-10 10:16 ` [PATCH v1 04/10] fscrypt: reduce special-casing of IV_INO_LBLK_32 Sweet Tea Dorminy
2023-04-10 10:16 ` [PATCH v1 05/10] fscrypt: make infos have a pointer to prepared keys Sweet Tea Dorminy
2023-04-10 10:16 ` [PATCH v1 06/10] fscrypt: move all the shared mode key setup deeper Sweet Tea Dorminy
2023-04-10 10:16 ` [PATCH v1 07/10] fscrypt: make ci->ci_direct_key a bool not a pointer Sweet Tea Dorminy
2023-04-10 10:16 ` Sweet Tea Dorminy [this message]
2023-04-10 10:16 ` [PATCH v1 09/10] fscrypt: explicitly track prepared parts of key Sweet Tea Dorminy
2023-04-10 10:16 ` [PATCH v1 10/10] fscrypt: split key alloc and preparation Sweet Tea Dorminy
2023-04-10 19:19 ` [PATCH v1 00/10] fscrypt: rearrangements preliminary to extent encryption Eric Biggers
2023-04-10 19:40   ` Sweet Tea Dorminy

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=c821c5e73252b47a57ccc80d805a86510462f005.1681116740.git.sweettea-kernel@dorminy.me \
    --to=sweettea-kernel@dorminy.me \
    --cc=ebiggers@kernel.org \
    --cc=jaegeuk@kernel.org \
    --cc=kernel-team@meta.com \
    --cc=linux-fscrypt@vger.kernel.org \
    --cc=tytso@mit.edu \
    /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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).