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 9*3fd945a7SJeff 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 162d332d5bSJeff Layton struct ceph_fscrypt_auth { 172d332d5bSJeff Layton __le32 cfa_version; 182d332d5bSJeff Layton __le32 cfa_blob_len; 192d332d5bSJeff Layton u8 cfa_blob[FSCRYPT_SET_CONTEXT_MAX_SIZE]; 202d332d5bSJeff Layton } __packed; 212d332d5bSJeff Layton 222d332d5bSJeff Layton #define CEPH_FSCRYPT_AUTH_VERSION 1 232d332d5bSJeff Layton static inline u32 ceph_fscrypt_auth_len(struct ceph_fscrypt_auth *fa) 242d332d5bSJeff Layton { 252d332d5bSJeff Layton u32 ctxsize = le32_to_cpu(fa->cfa_blob_len); 262d332d5bSJeff Layton 272d332d5bSJeff Layton return offsetof(struct ceph_fscrypt_auth, cfa_blob) + ctxsize; 282d332d5bSJeff Layton } 292d332d5bSJeff Layton 302d332d5bSJeff Layton #ifdef CONFIG_FS_ENCRYPTION 3164e86f63SLuís Henriques /* 3264e86f63SLuís Henriques * We want to encrypt filenames when creating them, but the encrypted 3364e86f63SLuís Henriques * versions of those names may have illegal characters in them. To mitigate 3464e86f63SLuís Henriques * that, we base64 encode them, but that gives us a result that can exceed 3564e86f63SLuís Henriques * NAME_MAX. 3664e86f63SLuís Henriques * 3764e86f63SLuís Henriques * Follow a similar scheme to fscrypt itself, and cap the filename to a 3864e86f63SLuís Henriques * smaller size. If the ciphertext name is longer than the value below, then 3964e86f63SLuís Henriques * sha256 hash the remaining bytes. 4064e86f63SLuís Henriques * 4164e86f63SLuís Henriques * For the fscrypt_nokey_name struct the dirhash[2] member is useless in ceph 4264e86f63SLuís Henriques * so the corresponding struct will be: 4364e86f63SLuís Henriques * 4464e86f63SLuís Henriques * struct fscrypt_ceph_nokey_name { 4564e86f63SLuís Henriques * u8 bytes[157]; 4664e86f63SLuís Henriques * u8 sha256[SHA256_DIGEST_SIZE]; 4764e86f63SLuís Henriques * }; // 180 bytes => 240 bytes base64-encoded, which is <= NAME_MAX (255) 4864e86f63SLuís Henriques * 4964e86f63SLuís Henriques * (240 bytes is the maximum size allowed for snapshot names to take into 5064e86f63SLuís Henriques * account the format: '_<SNAPSHOT-NAME>_<INODE-NUMBER>'.) 5164e86f63SLuís Henriques * 5264e86f63SLuís Henriques * Note that for long names that end up having their tail portion hashed, we 5364e86f63SLuís Henriques * must also store the full encrypted name (in the dentry's alternate_name 5464e86f63SLuís Henriques * field). 5564e86f63SLuís Henriques */ 5664e86f63SLuís Henriques #define CEPH_NOHASH_NAME_MAX (180 - SHA256_DIGEST_SIZE) 5764e86f63SLuís Henriques 5864e86f63SLuís Henriques #define CEPH_BASE64_CHARS(nbytes) DIV_ROUND_UP((nbytes) * 4, 3) 5964e86f63SLuís Henriques 6064e86f63SLuís Henriques int ceph_base64_encode(const u8 *src, int srclen, char *dst); 6164e86f63SLuís Henriques int ceph_base64_decode(const char *src, int srclen, u8 *dst); 6264e86f63SLuís Henriques 632d332d5bSJeff Layton void ceph_fscrypt_set_ops(struct super_block *sb); 642d332d5bSJeff Layton 656b5717bdSJeff Layton void ceph_fscrypt_free_dummy_policy(struct ceph_fs_client *fsc); 666b5717bdSJeff Layton 676b5717bdSJeff Layton int ceph_fscrypt_prepare_context(struct inode *dir, struct inode *inode, 686b5717bdSJeff Layton struct ceph_acl_sec_ctx *as); 696b5717bdSJeff Layton void ceph_fscrypt_as_ctx_to_req(struct ceph_mds_request *req, 706b5717bdSJeff Layton struct ceph_acl_sec_ctx *as); 71*3fd945a7SJeff Layton int ceph_encode_encrypted_fname(const struct inode *parent, 72*3fd945a7SJeff Layton struct dentry *dentry, char *buf); 736b5717bdSJeff Layton 742d332d5bSJeff Layton #else /* CONFIG_FS_ENCRYPTION */ 752d332d5bSJeff Layton 762d332d5bSJeff Layton static inline void ceph_fscrypt_set_ops(struct super_block *sb) 772d332d5bSJeff Layton { 782d332d5bSJeff Layton } 792d332d5bSJeff Layton 806b5717bdSJeff Layton static inline void ceph_fscrypt_free_dummy_policy(struct ceph_fs_client *fsc) 816b5717bdSJeff Layton { 826b5717bdSJeff Layton } 836b5717bdSJeff Layton 846b5717bdSJeff Layton static inline int ceph_fscrypt_prepare_context(struct inode *dir, 856b5717bdSJeff Layton struct inode *inode, 866b5717bdSJeff Layton struct ceph_acl_sec_ctx *as) 876b5717bdSJeff Layton { 886b5717bdSJeff Layton if (IS_ENCRYPTED(dir)) 896b5717bdSJeff Layton return -EOPNOTSUPP; 906b5717bdSJeff Layton return 0; 916b5717bdSJeff Layton } 926b5717bdSJeff Layton 936b5717bdSJeff Layton static inline void ceph_fscrypt_as_ctx_to_req(struct ceph_mds_request *req, 946b5717bdSJeff Layton struct ceph_acl_sec_ctx *as_ctx) 956b5717bdSJeff Layton { 966b5717bdSJeff Layton } 97*3fd945a7SJeff Layton 98*3fd945a7SJeff Layton static inline int ceph_encode_encrypted_fname(const struct inode *parent, 99*3fd945a7SJeff Layton struct dentry *dentry, char *buf) 100*3fd945a7SJeff Layton { 101*3fd945a7SJeff Layton return -EOPNOTSUPP; 102*3fd945a7SJeff Layton } 1032d332d5bSJeff Layton #endif /* CONFIG_FS_ENCRYPTION */ 1042d332d5bSJeff Layton 1052d332d5bSJeff Layton #endif 106