linux-btrfs.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Josef Bacik <josef@toxicpanda.com>
To: linux-btrfs@vger.kernel.org, kernel-team@fb.com
Cc: Omar Sandoval <osandov@osandov.com>,
	Sweet Tea Dorminy <sweettea-kernel@dorminy.me>
Subject: [PATCH v5 07/52] fscrypt: expose fscrypt_nokey_name
Date: Wed, 24 Jan 2024 12:18:29 -0500	[thread overview]
Message-ID: <132b64edf1e6b705995fb1a6dc2f194527f6be75.1706116485.git.josef@toxicpanda.com> (raw)
In-Reply-To: <cover.1706116485.git.josef@toxicpanda.com>

From: Omar Sandoval <osandov@osandov.com>

btrfs stores its data structures, including filenames in directories, in
its own buffer implementation, struct extent_buffer, composed of
several non-contiguous pages. We could copy filenames into a
temporary buffer and use fscrypt_match_name() against that buffer, such
extensive memcpying would be expensive. Instead, exposing
fscrypt_nokey_name as in this change allows btrfs to recapitulate
fscrypt_match_name() using methods on struct extent_buffer instead of
dealing with a raw byte array.

Signed-off-by: Omar Sandoval <osandov@osandov.com>
Signed-off-by: Sweet Tea Dorminy <sweettea-kernel@dorminy.me>
Signed-off-by: Josef Bacik <josef@toxicpanda.com>
---
 fs/crypto/fname.c       | 36 ------------------------------------
 include/linux/fscrypt.h | 36 ++++++++++++++++++++++++++++++++++++
 2 files changed, 36 insertions(+), 36 deletions(-)

diff --git a/fs/crypto/fname.c b/fs/crypto/fname.c
index 7b3fc189593a..3e8210036f15 100644
--- a/fs/crypto/fname.c
+++ b/fs/crypto/fname.c
@@ -25,42 +25,6 @@
  */
 #define FSCRYPT_FNAME_MIN_MSG_LEN 16
 
-/*
- * struct fscrypt_nokey_name - identifier for directory entry when key is absent
- *
- * When userspace lists an encrypted directory without access to the key, the
- * filesystem must present a unique "no-key name" for each filename that allows
- * it to find the directory entry again if requested.  Naively, that would just
- * mean using the ciphertext filenames.  However, since the ciphertext filenames
- * can contain illegal characters ('\0' and '/'), they must be encoded in some
- * way.  We use base64url.  But that can cause names to exceed NAME_MAX (255
- * bytes), so we also need to use a strong hash to abbreviate long names.
- *
- * The filesystem may also need another kind of hash, the "dirhash", to quickly
- * find the directory entry.  Since filesystems normally compute the dirhash
- * over the on-disk filename (i.e. the ciphertext), it's not computable from
- * no-key names that abbreviate the ciphertext using the strong hash to fit in
- * NAME_MAX.  It's also not computable if it's a keyed hash taken over the
- * plaintext (but it may still be available in the on-disk directory entry);
- * casefolded directories use this type of dirhash.  At least in these cases,
- * each no-key name must include the name's dirhash too.
- *
- * To meet all these requirements, we base64url-encode the following
- * variable-length structure.  It contains the dirhash, or 0's if the filesystem
- * didn't provide one; up to 149 bytes of the ciphertext name; and for
- * ciphertexts longer than 149 bytes, also the SHA-256 of the remaining bytes.
- *
- * This ensures that each no-key name contains everything needed to find the
- * directory entry again, contains only legal characters, doesn't exceed
- * NAME_MAX, is unambiguous unless there's a SHA-256 collision, and that we only
- * take the performance hit of SHA-256 on very long filenames (which are rare).
- */
-struct fscrypt_nokey_name {
-	u32 dirhash[2];
-	u8 bytes[149];
-	u8 sha256[SHA256_DIGEST_SIZE];
-}; /* 189 bytes => 252 bytes base64url-encoded, which is <= NAME_MAX (255) */
-
 /*
  * Decoded size of max-size no-key name, i.e. a name that was abbreviated using
  * the strong hash and thus includes the 'sha256' field.  This isn't simply
diff --git a/include/linux/fscrypt.h b/include/linux/fscrypt.h
index ea3033956208..fc8b2156e444 100644
--- a/include/linux/fscrypt.h
+++ b/include/linux/fscrypt.h
@@ -56,6 +56,42 @@ struct fscrypt_name {
 #define fname_name(p)		((p)->disk_name.name)
 #define fname_len(p)		((p)->disk_name.len)
 
+/*
+ * struct fscrypt_nokey_name - identifier for directory entry when key is absent
+ *
+ * When userspace lists an encrypted directory without access to the key, the
+ * filesystem must present a unique "no-key name" for each filename that allows
+ * it to find the directory entry again if requested.  Naively, that would just
+ * mean using the ciphertext filenames.  However, since the ciphertext filenames
+ * can contain illegal characters ('\0' and '/'), they must be encoded in some
+ * way.  We use base64url.  But that can cause names to exceed NAME_MAX (255
+ * bytes), so we also need to use a strong hash to abbreviate long names.
+ *
+ * The filesystem may also need another kind of hash, the "dirhash", to quickly
+ * find the directory entry.  Since filesystems normally compute the dirhash
+ * over the on-disk filename (i.e. the ciphertext), it's not computable from
+ * no-key names that abbreviate the ciphertext using the strong hash to fit in
+ * NAME_MAX.  It's also not computable if it's a keyed hash taken over the
+ * plaintext (but it may still be available in the on-disk directory entry);
+ * casefolded directories use this type of dirhash.  At least in these cases,
+ * each no-key name must include the name's dirhash too.
+ *
+ * To meet all these requirements, we base64url-encode the following
+ * variable-length structure.  It contains the dirhash, or 0's if the filesystem
+ * didn't provide one; up to 149 bytes of the ciphertext name; and for
+ * ciphertexts longer than 149 bytes, also the SHA-256 of the remaining bytes.
+ *
+ * This ensures that each no-key name contains everything needed to find the
+ * directory entry again, contains only legal characters, doesn't exceed
+ * NAME_MAX, is unambiguous unless there's a SHA-256 collision, and that we only
+ * take the performance hit of SHA-256 on very long filenames (which are rare).
+ */
+struct fscrypt_nokey_name {
+	u32 dirhash[2];
+	u8 bytes[149];
+	u8 sha256[32];
+}; /* 189 bytes => 252 bytes base64url-encoded, which is <= NAME_MAX (255) */
+
 /* Maximum value for the third parameter of fscrypt_operations.set_context(). */
 #define FSCRYPT_SET_CONTEXT_MAX_SIZE	40
 
-- 
2.43.0


  parent reply	other threads:[~2024-01-24 17:19 UTC|newest]

Thread overview: 59+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-01-24 17:18 [PATCH v5 00/52] btrfs: add fscrypt support Josef Bacik
2024-01-24 17:18 ` [PATCH v5 01/52] fscrypt: add per-extent encryption support Josef Bacik
2024-01-24 17:18 ` [PATCH v5 02/52] fscrypt: allow inline encryption for extent based encryption Josef Bacik
2024-01-24 17:18 ` [PATCH v5 03/52] fscrypt: add a fscrypt_inode_open helper Josef Bacik
2024-01-24 17:18 ` [PATCH v5 04/52] fscrypt: conditionally don't wipe mk secret until the last active user is done Josef Bacik
2024-01-24 17:18 ` [PATCH v5 05/52] blk-crypto: add a process bio callback Josef Bacik
2024-01-24 17:18 ` [PATCH v5 06/52] fscrypt: add a process_bio hook to fscrypt_operations Josef Bacik
2024-01-24 17:18 ` Josef Bacik [this message]
2024-01-24 17:18 ` [PATCH v5 08/52] fscrypt: add documentation about extent encryption Josef Bacik
2024-01-24 17:18 ` [PATCH v5 09/52] btrfs: add infrastructure for safe em freeing Josef Bacik
2024-01-24 19:49   ` Boris Burkov
2024-01-24 17:18 ` [PATCH v5 10/52] btrfs: disable various operations on encrypted inodes Josef Bacik
2024-01-24 19:53   ` Boris Burkov
2024-01-24 17:18 ` [PATCH v5 11/52] btrfs: disable verity " Josef Bacik
2024-01-24 19:53   ` Boris Burkov
2024-01-24 17:18 ` [PATCH v5 12/52] btrfs: start using fscrypt hooks Josef Bacik
2024-01-24 17:18 ` [PATCH v5 13/52] btrfs: add inode encryption contexts Josef Bacik
2024-01-24 17:18 ` [PATCH v5 14/52] btrfs: add new FEATURE_INCOMPAT_ENCRYPT flag Josef Bacik
2024-01-24 17:18 ` [PATCH v5 15/52] btrfs: adapt readdir for encrypted and nokey names Josef Bacik
2024-01-24 17:18 ` [PATCH v5 16/52] btrfs: handle " Josef Bacik
2024-01-24 17:18 ` [PATCH v5 17/52] btrfs: implement fscrypt ioctls Josef Bacik
2024-01-24 17:18 ` [PATCH v5 18/52] btrfs: gate encryption behind BTRFS_DEBUG Josef Bacik
2024-01-24 17:18 ` [PATCH v5 19/52] btrfs: select encryption dependencies if FS_ENCRYPTION Josef Bacik
2024-01-24 17:18 ` [PATCH v5 20/52] btrfs: add get_devices hook for fscrypt Josef Bacik
2024-01-24 17:18 ` [PATCH v5 21/52] btrfs: set file extent encryption excplicitly Josef Bacik
2024-01-24 17:18 ` [PATCH v5 22/52] btrfs: add fscrypt_info and encryption_type to extent_map Josef Bacik
2024-01-24 17:18 ` [PATCH v5 23/52] btrfs: add fscrypt_info and encryption_type to ordered_extent Josef Bacik
2024-01-24 17:18 ` [PATCH v5 24/52] btrfs: plumb through setting the fscrypt_info for ordered extents Josef Bacik
2024-01-24 17:18 ` [PATCH v5 25/52] btrfs: plumb the fscrypt extent context through create_io_em Josef Bacik
2024-01-24 17:18 ` [PATCH v5 26/52] btrfs: populate the ordered_extent with the fscrypt context Josef Bacik
2024-01-24 17:18 ` [PATCH v5 27/52] btrfs: keep track of fscrypt info and orig_start for dio reads Josef Bacik
2024-01-24 17:18 ` [PATCH v5 28/52] btrfs: add an optional encryption context to the end of file extents Josef Bacik
2024-01-24 17:18 ` [PATCH v5 29/52] btrfs: explicitly track file extent length for replace and drop Josef Bacik
2024-01-24 17:18 ` [PATCH v5 30/52] btrfs: pass through fscrypt_extent_info to the file extent helpers Josef Bacik
2024-01-24 17:18 ` [PATCH v5 31/52] btrfs: implement the fscrypt extent encryption hooks Josef Bacik
2024-01-24 17:18 ` [PATCH v5 32/52] btrfs: setup fscrypt_extent_info for new extents Josef Bacik
2024-01-24 17:18 ` [PATCH v5 33/52] btrfs: populate ordered_extent with the orig offset Josef Bacik
2024-01-24 17:18 ` [PATCH v5 34/52] btrfs: set the bio fscrypt context when applicable Josef Bacik
2024-01-24 17:18 ` [PATCH v5 35/52] btrfs: add a bio argument to btrfs_csum_one_bio Josef Bacik
2024-01-24 17:18 ` [PATCH v5 36/52] btrfs: add orig_logical to btrfs_bio Josef Bacik
2024-01-24 17:18 ` [PATCH v5 37/52] btrfs: limit encrypted writes to 256 segments Josef Bacik
2024-01-24 17:19 ` [PATCH v5 38/52] btrfs: implement process_bio cb for fscrypt Josef Bacik
2024-01-24 17:19 ` [PATCH v5 39/52] btrfs: implement read repair for encryption Josef Bacik
2024-01-24 17:19 ` [PATCH v5 40/52] btrfs: add test_dummy_encryption support Josef Bacik
2024-01-24 17:19 ` [PATCH v5 41/52] btrfs: don't rewrite ret from inode_permission Josef Bacik
2024-01-24 17:19 ` [PATCH v5 42/52] btrfs: move inode_to_path higher in backref.c Josef Bacik
2024-01-24 17:19 ` [PATCH v5 43/52] btrfs: make btrfs_ref_to_path handle encrypted filenames Josef Bacik
2024-01-24 17:19 ` [PATCH v5 44/52] btrfs: don't search back for dir inode item in INO_LOOKUP_USER Josef Bacik
2024-01-24 17:19 ` [PATCH v5 45/52] btrfs: deal with encrypted symlinks in send Josef Bacik
2024-01-24 17:19 ` [PATCH v5 46/52] btrfs: decrypt file names for send Josef Bacik
2024-01-24 17:19 ` [PATCH v5 47/52] btrfs: load the inode context before sending writes Josef Bacik
2024-01-24 17:19 ` [PATCH v5 48/52] btrfs: set the appropriate free space settings in reconfigure Josef Bacik
2024-01-24 17:19 ` [PATCH v5 49/52] btrfs: support encryption with log replay Josef Bacik
2024-01-24 17:19 ` [PATCH v5 50/52] btrfs: disable auto defrag on encrypted files Josef Bacik
2024-01-24 17:19 ` [PATCH v5 51/52] btrfs: disable encryption on RAID5/6 Josef Bacik
2024-01-24 17:19 ` [PATCH v5 52/52] btrfs: disable send if we have encryption enabled Josef Bacik
2024-01-24 19:28   ` Boris Burkov
2024-01-24 19:18 ` [PATCH v5 00/52] btrfs: add fscrypt support Neal Gompa
2024-01-24 19:58   ` Josef Bacik

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=132b64edf1e6b705995fb1a6dc2f194527f6be75.1706116485.git.josef@toxicpanda.com \
    --to=josef@toxicpanda.com \
    --cc=kernel-team@fb.com \
    --cc=linux-btrfs@vger.kernel.org \
    --cc=osandov@osandov.com \
    --cc=sweettea-kernel@dorminy.me \
    /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 NNTP newsgroup(s).