All of lore.kernel.org
 help / color / mirror / Atom feed
From: Jeff Layton <jlayton@kernel.org>
To: ceph-devel@vger.kernel.org, linux-fscrypt@vger.kernel.org
Cc: linux-fsdevel@vger.kernel.org
Subject: [RFC PATCH v3 02/16] fscrypt: export fscrypt_base64_encode and fscrypt_base64_decode
Date: Mon, 14 Sep 2020 15:16:53 -0400	[thread overview]
Message-ID: <20200914191707.380444-3-jlayton@kernel.org> (raw)
In-Reply-To: <20200914191707.380444-1-jlayton@kernel.org>

Ceph will need to base64-encode some encrypted inode names, so make
these routines, and FSCRYPT_BASE64_CHARS available to modules.

Signed-off-by: Jeff Layton <jlayton@kernel.org>
---
 fs/crypto/fname.c       | 59 ++++++++++++++++++++++++++++++++++-------
 include/linux/fscrypt.h |  4 +++
 2 files changed, 53 insertions(+), 10 deletions(-)

diff --git a/fs/crypto/fname.c b/fs/crypto/fname.c
index eb13408b50a7..a1cb6c2c50c4 100644
--- a/fs/crypto/fname.c
+++ b/fs/crypto/fname.c
@@ -187,10 +187,8 @@ static int fname_decrypt(const struct inode *inode,
 static const char lookup_table[65] =
 	"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+,";
 
-#define BASE64_CHARS(nbytes)	DIV_ROUND_UP((nbytes) * 4, 3)
-
 /**
- * base64_encode() - base64-encode some bytes
+ * fscrypt_base64_encode() - base64-encode some bytes
  * @src: the bytes to encode
  * @len: number of bytes to encode
  * @dst: (output) the base64-encoded string.  Not NUL-terminated.
@@ -200,7 +198,7 @@ static const char lookup_table[65] =
  *
  * Return: length of the encoded string
  */
-static int base64_encode(const u8 *src, int len, char *dst)
+int fscrypt_base64_encode(const u8 *src, int len, char *dst)
 {
 	int i, bits = 0, ac = 0;
 	char *cp = dst;
@@ -218,8 +216,9 @@ static int base64_encode(const u8 *src, int len, char *dst)
 		*cp++ = lookup_table[ac & 0x3f];
 	return cp - dst;
 }
+EXPORT_SYMBOL(fscrypt_base64_encode);
 
-static int base64_decode(const char *src, int len, u8 *dst)
+int fscrypt_base64_decode(const char *src, int len, u8 *dst)
 {
 	int i, bits = 0, ac = 0;
 	const char *p;
@@ -241,6 +240,7 @@ static int base64_decode(const char *src, int len, u8 *dst)
 		return -1;
 	return cp - dst;
 }
+EXPORT_SYMBOL(fscrypt_base64_decode);
 
 bool fscrypt_fname_encrypted_size(const union fscrypt_policy *policy,
 				  u32 orig_len, u32 max_len,
@@ -272,7 +272,7 @@ bool fscrypt_fname_encrypted_size(const union fscrypt_policy *policy,
 int fscrypt_fname_alloc_buffer(u32 max_encrypted_len,
 			       struct fscrypt_str *crypto_str)
 {
-	const u32 max_encoded_len = BASE64_CHARS(FSCRYPT_NOKEY_NAME_MAX);
+	const u32 max_encoded_len = FSCRYPT_BASE64_CHARS(FSCRYPT_NOKEY_NAME_MAX);
 	u32 max_presented_len;
 
 	max_presented_len = max(max_encoded_len, max_encrypted_len);
@@ -300,6 +300,45 @@ void fscrypt_fname_free_buffer(struct fscrypt_str *crypto_str)
 }
 EXPORT_SYMBOL(fscrypt_fname_free_buffer);
 
+void fscrypt_encode_nokey_name(u32 hash, u32 minor_hash,
+			     const struct fscrypt_str *iname,
+			     struct fscrypt_str *oname)
+{
+	struct fscrypt_nokey_name nokey_name;
+	u32 size; /* size of the unencoded no-key name */
+
+	/*
+	 * Sanity check that struct fscrypt_nokey_name doesn't have padding
+	 * between fields and that its encoded size never exceeds NAME_MAX.
+	 */
+	BUILD_BUG_ON(offsetofend(struct fscrypt_nokey_name, dirhash) !=
+		     offsetof(struct fscrypt_nokey_name, bytes));
+	BUILD_BUG_ON(offsetofend(struct fscrypt_nokey_name, bytes) !=
+		     offsetof(struct fscrypt_nokey_name, sha256));
+	BUILD_BUG_ON(FSCRYPT_BASE64_CHARS(FSCRYPT_NOKEY_NAME_MAX) > NAME_MAX);
+
+	if (hash) {
+		nokey_name.dirhash[0] = hash;
+		nokey_name.dirhash[1] = minor_hash;
+	} else {
+		nokey_name.dirhash[0] = 0;
+		nokey_name.dirhash[1] = 0;
+	}
+	if (iname->len <= sizeof(nokey_name.bytes)) {
+		memcpy(nokey_name.bytes, iname->name, iname->len);
+		size = offsetof(struct fscrypt_nokey_name, bytes[iname->len]);
+	} else {
+		memcpy(nokey_name.bytes, iname->name, sizeof(nokey_name.bytes));
+		/* Compute strong hash of remaining part of name. */
+		fscrypt_do_sha256(&iname->name[sizeof(nokey_name.bytes)],
+				  iname->len - sizeof(nokey_name.bytes),
+				  nokey_name.sha256);
+		size = FSCRYPT_NOKEY_NAME_MAX;
+	}
+	oname->len = fscrypt_base64_encode((const u8 *)&nokey_name, size, oname->name);
+}
+EXPORT_SYMBOL(fscrypt_encode_nokey_name);
+
 /**
  * fscrypt_fname_disk_to_usr() - convert an encrypted filename to
  *				 user-presentable form
@@ -351,7 +390,7 @@ int fscrypt_fname_disk_to_usr(const struct inode *inode,
 		     offsetof(struct fscrypt_nokey_name, bytes));
 	BUILD_BUG_ON(offsetofend(struct fscrypt_nokey_name, bytes) !=
 		     offsetof(struct fscrypt_nokey_name, sha256));
-	BUILD_BUG_ON(BASE64_CHARS(FSCRYPT_NOKEY_NAME_MAX) > NAME_MAX);
+	BUILD_BUG_ON(FSCRYPT_BASE64_CHARS(FSCRYPT_NOKEY_NAME_MAX) > NAME_MAX);
 
 	if (hash) {
 		nokey_name.dirhash[0] = hash;
@@ -371,7 +410,7 @@ int fscrypt_fname_disk_to_usr(const struct inode *inode,
 				  nokey_name.sha256);
 		size = FSCRYPT_NOKEY_NAME_MAX;
 	}
-	oname->len = base64_encode((const u8 *)&nokey_name, size, oname->name);
+	oname->len = fscrypt_base64_encode((const u8 *)&nokey_name, size, oname->name);
 	return 0;
 }
 EXPORT_SYMBOL(fscrypt_fname_disk_to_usr);
@@ -445,14 +484,14 @@ int fscrypt_setup_filename(struct inode *dir, const struct qstr *iname,
 	 * user-supplied name
 	 */
 
-	if (iname->len > BASE64_CHARS(FSCRYPT_NOKEY_NAME_MAX))
+	if (iname->len > FSCRYPT_BASE64_CHARS(FSCRYPT_NOKEY_NAME_MAX))
 		return -ENOENT;
 
 	fname->crypto_buf.name = kmalloc(FSCRYPT_NOKEY_NAME_MAX, GFP_KERNEL);
 	if (fname->crypto_buf.name == NULL)
 		return -ENOMEM;
 
-	ret = base64_decode(iname->name, iname->len, fname->crypto_buf.name);
+	ret = fscrypt_base64_decode(iname->name, iname->len, fname->crypto_buf.name);
 	if (ret < (int)offsetof(struct fscrypt_nokey_name, bytes[1]) ||
 	    (ret > offsetof(struct fscrypt_nokey_name, sha256) &&
 	     ret != FSCRYPT_NOKEY_NAME_MAX)) {
diff --git a/include/linux/fscrypt.h b/include/linux/fscrypt.h
index b3b0c5675c6b..95dddba3ed00 100644
--- a/include/linux/fscrypt.h
+++ b/include/linux/fscrypt.h
@@ -182,6 +182,10 @@ void fscrypt_free_inode(struct inode *inode);
 int fscrypt_drop_inode(struct inode *inode);
 
 /* fname.c */
+#define FSCRYPT_BASE64_CHARS(nbytes)	DIV_ROUND_UP((nbytes) * 4, 3)
+
+int fscrypt_base64_encode(const u8 *src, int len, char *dst);
+int fscrypt_base64_decode(const char *src, int len, u8 *dst);
 int fscrypt_setup_filename(struct inode *inode, const struct qstr *iname,
 			   int lookup, struct fscrypt_name *fname);
 
-- 
2.26.2


  parent reply	other threads:[~2020-09-14 19:19 UTC|newest]

Thread overview: 48+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-09-14 19:16 [RFC PATCH v3 00/16] ceph+fscrypt: context, filename and symlink support Jeff Layton
2020-09-14 19:16 ` [RFC PATCH v3 01/16] vfs: export new_inode_pseudo Jeff Layton
2020-09-14 23:33   ` Eric Biggers
2020-09-23  3:41   ` Al Viro
2020-09-23 11:19     ` Jeff Layton
2020-09-14 19:16 ` Jeff Layton [this message]
2020-09-14 23:44   ` [RFC PATCH v3 02/16] fscrypt: export fscrypt_base64_encode and fscrypt_base64_decode Eric Biggers
2020-09-14 19:16 ` [RFC PATCH v3 03/16] fscrypt: export fscrypt_d_revalidate Jeff Layton
2020-09-15  0:04   ` Eric Biggers
2020-09-14 19:16 ` [RFC PATCH v3 04/16] fscrypt: add fscrypt_context_for_new_inode Jeff Layton
2020-09-15  0:15   ` Eric Biggers
2020-09-14 19:16 ` [RFC PATCH v3 05/16] fscrypt: make fscrypt_fname_disk_to_usr return whether result is nokey name Jeff Layton
2020-09-15  0:23   ` Eric Biggers
2020-09-14 19:16 ` [RFC PATCH v3 06/16] ceph: add fscrypt ioctls Jeff Layton
2020-09-15  0:45   ` Eric Biggers
2020-09-15 12:08     ` Jeff Layton
2020-09-14 19:16 ` [RFC PATCH v3 07/16] ceph: crypto context handling for ceph Jeff Layton
2020-09-15  1:00   ` Eric Biggers
2020-09-14 19:16 ` [RFC PATCH v3 08/16] ceph: implement -o test_dummy_encryption mount option Jeff Layton
2020-09-15  1:23   ` Eric Biggers
2020-09-16 12:49     ` Jeff Layton
2020-09-14 19:17 ` [RFC PATCH v3 09/16] ceph: preallocate inode for ops that may create one Jeff Layton
2020-09-15  1:30   ` Eric Biggers
2020-09-16 12:41     ` Jeff Layton
2020-09-14 19:17 ` [RFC PATCH v3 10/16] ceph: add routine to create context prior to RPC Jeff Layton
2020-09-15  1:37   ` Eric Biggers
2020-09-16 12:18     ` Jeff Layton
2020-09-14 19:17 ` [RFC PATCH v3 11/16] ceph: make ceph_msdc_build_path use ref-walk Jeff Layton
2020-09-14 19:17 ` [RFC PATCH v3 12/16] ceph: add encrypted fname handling to ceph_mdsc_build_path Jeff Layton
2020-09-15  1:41   ` Eric Biggers
2020-09-16 12:30     ` Jeff Layton
2020-09-16 17:36       ` Eric Biggers
2020-09-16 18:04         ` Jeff Layton
2020-09-16 18:42           ` Eric Biggers
2020-09-14 19:17 ` [RFC PATCH v3 13/16] ceph: make d_revalidate call fscrypt revalidator for encrypted dentries Jeff Layton
2020-09-14 19:17 ` [RFC PATCH v3 14/16] ceph: add support to readdir for encrypted filenames Jeff Layton
2020-09-15  1:57   ` Eric Biggers
2020-09-15 13:27     ` Jeff Layton
2020-09-15 20:40       ` Eric Biggers
2020-09-16 12:16         ` Jeff Layton
2020-09-14 19:17 ` [RFC PATCH v3 15/16] ceph: add fscrypt support to ceph_fill_trace Jeff Layton
2020-09-14 19:17 ` [RFC PATCH v3 16/16] ceph: create symlinks with encrypted and base64-encoded targets Jeff Layton
2020-09-15  2:07   ` Eric Biggers
2020-09-15 14:05     ` Jeff Layton
2020-09-15 20:49       ` Eric Biggers
2020-09-16 12:15         ` Jeff Layton
2020-09-15  2:13 ` [RFC PATCH v3 00/16] ceph+fscrypt: context, filename and symlink support Eric Biggers
2020-09-15 13:38   ` Jeff Layton

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=20200914191707.380444-3-jlayton@kernel.org \
    --to=jlayton@kernel.org \
    --cc=ceph-devel@vger.kernel.org \
    --cc=linux-fscrypt@vger.kernel.org \
    --cc=linux-fsdevel@vger.kernel.org \
    /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.