summaryrefslogtreecommitdiffstats
path: root/fs/ceph/crypto.h
diff options
context:
space:
mode:
authorLuís Henriques <lhenriques@suse.de>2022-04-18 14:59:56 +0100
committerIlya Dryomov <idryomov@gmail.com>2023-08-22 09:01:48 +0200
commit64e86f632bf148d007946c52781781eb8380d416 (patch)
treed1f849ac0190eaa1fadb531ec54d3335ac0c36e5 /fs/ceph/crypto.h
parentb7b53361c80b16ad461dbcb8a93e6e37578bac9b (diff)
downloadlinux-64e86f632bf148d007946c52781781eb8380d416.tar.gz
linux-64e86f632bf148d007946c52781781eb8380d416.tar.bz2
linux-64e86f632bf148d007946c52781781eb8380d416.zip
ceph: add base64 endcoding routines for encrypted names
The base64url encoding used by fscrypt includes the '_' character, which may cause problems in snapshot names (if the name starts with '_'). Thus, use the base64 encoding defined for IMAP mailbox names (RFC 3501), which uses '+' and ',' instead of '-' and '_'. Signed-off-by: Luís Henriques <lhenriques@suse.de> Reviewed-by: Jeff Layton <jlayton@kernel.org> Reviewed-by: Xiubo Li <xiubli@redhat.com> Reviewed-by: Milind Changire <mchangir@redhat.com> Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
Diffstat (limited to 'fs/ceph/crypto.h')
-rw-r--r--fs/ceph/crypto.h32
1 files changed, 32 insertions, 0 deletions
diff --git a/fs/ceph/crypto.h b/fs/ceph/crypto.h
index 642963f5442e..44eb3f9f8287 100644
--- a/fs/ceph/crypto.h
+++ b/fs/ceph/crypto.h
@@ -27,6 +27,38 @@ static inline u32 ceph_fscrypt_auth_len(struct ceph_fscrypt_auth *fa)
}
#ifdef CONFIG_FS_ENCRYPTION
+/*
+ * We want to encrypt filenames when creating them, but the encrypted
+ * versions of those names may have illegal characters in them. To mitigate
+ * that, we base64 encode them, but that gives us a result that can exceed
+ * NAME_MAX.
+ *
+ * Follow a similar scheme to fscrypt itself, and cap the filename to a
+ * smaller size. If the ciphertext name is longer than the value below, then
+ * sha256 hash the remaining bytes.
+ *
+ * For the fscrypt_nokey_name struct the dirhash[2] member is useless in ceph
+ * so the corresponding struct will be:
+ *
+ * struct fscrypt_ceph_nokey_name {
+ * u8 bytes[157];
+ * u8 sha256[SHA256_DIGEST_SIZE];
+ * }; // 180 bytes => 240 bytes base64-encoded, which is <= NAME_MAX (255)
+ *
+ * (240 bytes is the maximum size allowed for snapshot names to take into
+ * account the format: '_<SNAPSHOT-NAME>_<INODE-NUMBER>'.)
+ *
+ * Note that for long names that end up having their tail portion hashed, we
+ * must also store the full encrypted name (in the dentry's alternate_name
+ * field).
+ */
+#define CEPH_NOHASH_NAME_MAX (180 - SHA256_DIGEST_SIZE)
+
+#define CEPH_BASE64_CHARS(nbytes) DIV_ROUND_UP((nbytes) * 4, 3)
+
+int ceph_base64_encode(const u8 *src, int srclen, char *dst);
+int ceph_base64_decode(const char *src, int srclen, u8 *dst);
+
void ceph_fscrypt_set_ops(struct super_block *sb);
void ceph_fscrypt_free_dummy_policy(struct ceph_fs_client *fsc);