xref: /openbmc/linux/fs/ceph/crypto.h (revision 457117f0)
12d332d5bSJeff Layton /* SPDX-License-Identifier: GPL-2.0 */
22d332d5bSJeff Layton /*
32d332d5bSJeff Layton  * Ceph fscrypt functionality
42d332d5bSJeff Layton  */
52d332d5bSJeff Layton 
62d332d5bSJeff Layton #ifndef _CEPH_CRYPTO_H
72d332d5bSJeff Layton #define _CEPH_CRYPTO_H
82d332d5bSJeff Layton 
93fd945a7SJeff Layton #include <crypto/sha2.h>
102d332d5bSJeff Layton #include <linux/fscrypt.h>
112d332d5bSJeff Layton 
126b5717bdSJeff Layton struct ceph_fs_client;
136b5717bdSJeff Layton struct ceph_acl_sec_ctx;
146b5717bdSJeff Layton struct ceph_mds_request;
156b5717bdSJeff Layton 
16*457117f0SJeff Layton struct ceph_fname {
17*457117f0SJeff Layton 	struct inode	*dir;
18*457117f0SJeff Layton 	char		*name;		// b64 encoded, possibly hashed
19*457117f0SJeff Layton 	unsigned char	*ctext;		// binary crypttext (if any)
20*457117f0SJeff Layton 	u32		name_len;	// length of name buffer
21*457117f0SJeff Layton 	u32		ctext_len;	// length of crypttext
22*457117f0SJeff Layton };
23*457117f0SJeff Layton 
242d332d5bSJeff Layton struct ceph_fscrypt_auth {
252d332d5bSJeff Layton 	__le32	cfa_version;
262d332d5bSJeff Layton 	__le32	cfa_blob_len;
272d332d5bSJeff Layton 	u8	cfa_blob[FSCRYPT_SET_CONTEXT_MAX_SIZE];
282d332d5bSJeff Layton } __packed;
292d332d5bSJeff Layton 
302d332d5bSJeff Layton #define CEPH_FSCRYPT_AUTH_VERSION	1
312d332d5bSJeff Layton static inline u32 ceph_fscrypt_auth_len(struct ceph_fscrypt_auth *fa)
322d332d5bSJeff Layton {
332d332d5bSJeff Layton 	u32 ctxsize = le32_to_cpu(fa->cfa_blob_len);
342d332d5bSJeff Layton 
352d332d5bSJeff Layton 	return offsetof(struct ceph_fscrypt_auth, cfa_blob) + ctxsize;
362d332d5bSJeff Layton }
372d332d5bSJeff Layton 
382d332d5bSJeff Layton #ifdef CONFIG_FS_ENCRYPTION
3964e86f63SLuís Henriques /*
4064e86f63SLuís Henriques  * We want to encrypt filenames when creating them, but the encrypted
4164e86f63SLuís Henriques  * versions of those names may have illegal characters in them. To mitigate
4264e86f63SLuís Henriques  * that, we base64 encode them, but that gives us a result that can exceed
4364e86f63SLuís Henriques  * NAME_MAX.
4464e86f63SLuís Henriques  *
4564e86f63SLuís Henriques  * Follow a similar scheme to fscrypt itself, and cap the filename to a
4664e86f63SLuís Henriques  * smaller size. If the ciphertext name is longer than the value below, then
4764e86f63SLuís Henriques  * sha256 hash the remaining bytes.
4864e86f63SLuís Henriques  *
4964e86f63SLuís Henriques  * For the fscrypt_nokey_name struct the dirhash[2] member is useless in ceph
5064e86f63SLuís Henriques  * so the corresponding struct will be:
5164e86f63SLuís Henriques  *
5264e86f63SLuís Henriques  * struct fscrypt_ceph_nokey_name {
5364e86f63SLuís Henriques  *	u8 bytes[157];
5464e86f63SLuís Henriques  *	u8 sha256[SHA256_DIGEST_SIZE];
5564e86f63SLuís Henriques  * }; // 180 bytes => 240 bytes base64-encoded, which is <= NAME_MAX (255)
5664e86f63SLuís Henriques  *
5764e86f63SLuís Henriques  * (240 bytes is the maximum size allowed for snapshot names to take into
5864e86f63SLuís Henriques  *  account the format: '_<SNAPSHOT-NAME>_<INODE-NUMBER>'.)
5964e86f63SLuís Henriques  *
6064e86f63SLuís Henriques  * Note that for long names that end up having their tail portion hashed, we
6164e86f63SLuís Henriques  * must also store the full encrypted name (in the dentry's alternate_name
6264e86f63SLuís Henriques  * field).
6364e86f63SLuís Henriques  */
6464e86f63SLuís Henriques #define CEPH_NOHASH_NAME_MAX (180 - SHA256_DIGEST_SIZE)
6564e86f63SLuís Henriques 
6664e86f63SLuís Henriques #define CEPH_BASE64_CHARS(nbytes) DIV_ROUND_UP((nbytes) * 4, 3)
6764e86f63SLuís Henriques 
6864e86f63SLuís Henriques int ceph_base64_encode(const u8 *src, int srclen, char *dst);
6964e86f63SLuís Henriques int ceph_base64_decode(const char *src, int srclen, u8 *dst);
7064e86f63SLuís Henriques 
712d332d5bSJeff Layton void ceph_fscrypt_set_ops(struct super_block *sb);
722d332d5bSJeff Layton 
736b5717bdSJeff Layton void ceph_fscrypt_free_dummy_policy(struct ceph_fs_client *fsc);
746b5717bdSJeff Layton 
756b5717bdSJeff Layton int ceph_fscrypt_prepare_context(struct inode *dir, struct inode *inode,
766b5717bdSJeff Layton 				 struct ceph_acl_sec_ctx *as);
776b5717bdSJeff Layton void ceph_fscrypt_as_ctx_to_req(struct ceph_mds_request *req,
786b5717bdSJeff Layton 				struct ceph_acl_sec_ctx *as);
793fd945a7SJeff Layton int ceph_encode_encrypted_fname(const struct inode *parent,
803fd945a7SJeff Layton 				struct dentry *dentry, char *buf);
816b5717bdSJeff Layton 
82*457117f0SJeff Layton static inline int ceph_fname_alloc_buffer(struct inode *parent,
83*457117f0SJeff Layton 					  struct fscrypt_str *fname)
84*457117f0SJeff Layton {
85*457117f0SJeff Layton 	if (!IS_ENCRYPTED(parent))
86*457117f0SJeff Layton 		return 0;
87*457117f0SJeff Layton 	return fscrypt_fname_alloc_buffer(NAME_MAX, fname);
88*457117f0SJeff Layton }
89*457117f0SJeff Layton 
90*457117f0SJeff Layton static inline void ceph_fname_free_buffer(struct inode *parent,
91*457117f0SJeff Layton 					  struct fscrypt_str *fname)
92*457117f0SJeff Layton {
93*457117f0SJeff Layton 	if (IS_ENCRYPTED(parent))
94*457117f0SJeff Layton 		fscrypt_fname_free_buffer(fname);
95*457117f0SJeff Layton }
96*457117f0SJeff Layton 
97*457117f0SJeff Layton int ceph_fname_to_usr(const struct ceph_fname *fname, struct fscrypt_str *tname,
98*457117f0SJeff Layton 		      struct fscrypt_str *oname, bool *is_nokey);
99*457117f0SJeff Layton 
1002d332d5bSJeff Layton #else /* CONFIG_FS_ENCRYPTION */
1012d332d5bSJeff Layton 
1022d332d5bSJeff Layton static inline void ceph_fscrypt_set_ops(struct super_block *sb)
1032d332d5bSJeff Layton {
1042d332d5bSJeff Layton }
1052d332d5bSJeff Layton 
1066b5717bdSJeff Layton static inline void ceph_fscrypt_free_dummy_policy(struct ceph_fs_client *fsc)
1076b5717bdSJeff Layton {
1086b5717bdSJeff Layton }
1096b5717bdSJeff Layton 
1106b5717bdSJeff Layton static inline int ceph_fscrypt_prepare_context(struct inode *dir,
1116b5717bdSJeff Layton 					       struct inode *inode,
1126b5717bdSJeff Layton 					       struct ceph_acl_sec_ctx *as)
1136b5717bdSJeff Layton {
1146b5717bdSJeff Layton 	if (IS_ENCRYPTED(dir))
1156b5717bdSJeff Layton 		return -EOPNOTSUPP;
1166b5717bdSJeff Layton 	return 0;
1176b5717bdSJeff Layton }
1186b5717bdSJeff Layton 
1196b5717bdSJeff Layton static inline void ceph_fscrypt_as_ctx_to_req(struct ceph_mds_request *req,
1206b5717bdSJeff Layton 						struct ceph_acl_sec_ctx *as_ctx)
1216b5717bdSJeff Layton {
1226b5717bdSJeff Layton }
1233fd945a7SJeff Layton 
1243fd945a7SJeff Layton static inline int ceph_encode_encrypted_fname(const struct inode *parent,
1253fd945a7SJeff Layton 					      struct dentry *dentry, char *buf)
1263fd945a7SJeff Layton {
1273fd945a7SJeff Layton 	return -EOPNOTSUPP;
1283fd945a7SJeff Layton }
129*457117f0SJeff Layton 
130*457117f0SJeff Layton static inline int ceph_fname_alloc_buffer(struct inode *parent,
131*457117f0SJeff Layton 					  struct fscrypt_str *fname)
132*457117f0SJeff Layton {
133*457117f0SJeff Layton 	return 0;
134*457117f0SJeff Layton }
135*457117f0SJeff Layton 
136*457117f0SJeff Layton static inline void ceph_fname_free_buffer(struct inode *parent,
137*457117f0SJeff Layton 					  struct fscrypt_str *fname)
138*457117f0SJeff Layton {
139*457117f0SJeff Layton }
140*457117f0SJeff Layton 
141*457117f0SJeff Layton static inline int ceph_fname_to_usr(const struct ceph_fname *fname,
142*457117f0SJeff Layton 				    struct fscrypt_str *tname,
143*457117f0SJeff Layton 				    struct fscrypt_str *oname, bool *is_nokey)
144*457117f0SJeff Layton {
145*457117f0SJeff Layton 	oname->name = fname->name;
146*457117f0SJeff Layton 	oname->len = fname->name_len;
147*457117f0SJeff Layton 	return 0;
148*457117f0SJeff Layton }
1492d332d5bSJeff Layton #endif /* CONFIG_FS_ENCRYPTION */
1502d332d5bSJeff Layton 
1512d332d5bSJeff Layton #endif
152