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 92d332d5bSJeff Layton #include <linux/fscrypt.h> 102d332d5bSJeff Layton 116b5717bdSJeff Layton struct ceph_fs_client; 126b5717bdSJeff Layton struct ceph_acl_sec_ctx; 136b5717bdSJeff Layton struct ceph_mds_request; 146b5717bdSJeff Layton 152d332d5bSJeff Layton struct ceph_fscrypt_auth { 162d332d5bSJeff Layton __le32 cfa_version; 172d332d5bSJeff Layton __le32 cfa_blob_len; 182d332d5bSJeff Layton u8 cfa_blob[FSCRYPT_SET_CONTEXT_MAX_SIZE]; 192d332d5bSJeff Layton } __packed; 202d332d5bSJeff Layton 212d332d5bSJeff Layton #define CEPH_FSCRYPT_AUTH_VERSION 1 222d332d5bSJeff Layton static inline u32 ceph_fscrypt_auth_len(struct ceph_fscrypt_auth *fa) 232d332d5bSJeff Layton { 242d332d5bSJeff Layton u32 ctxsize = le32_to_cpu(fa->cfa_blob_len); 252d332d5bSJeff Layton 262d332d5bSJeff Layton return offsetof(struct ceph_fscrypt_auth, cfa_blob) + ctxsize; 272d332d5bSJeff Layton } 282d332d5bSJeff Layton 292d332d5bSJeff Layton #ifdef CONFIG_FS_ENCRYPTION 30*64e86f63SLuís Henriques /* 31*64e86f63SLuís Henriques * We want to encrypt filenames when creating them, but the encrypted 32*64e86f63SLuís Henriques * versions of those names may have illegal characters in them. To mitigate 33*64e86f63SLuís Henriques * that, we base64 encode them, but that gives us a result that can exceed 34*64e86f63SLuís Henriques * NAME_MAX. 35*64e86f63SLuís Henriques * 36*64e86f63SLuís Henriques * Follow a similar scheme to fscrypt itself, and cap the filename to a 37*64e86f63SLuís Henriques * smaller size. If the ciphertext name is longer than the value below, then 38*64e86f63SLuís Henriques * sha256 hash the remaining bytes. 39*64e86f63SLuís Henriques * 40*64e86f63SLuís Henriques * For the fscrypt_nokey_name struct the dirhash[2] member is useless in ceph 41*64e86f63SLuís Henriques * so the corresponding struct will be: 42*64e86f63SLuís Henriques * 43*64e86f63SLuís Henriques * struct fscrypt_ceph_nokey_name { 44*64e86f63SLuís Henriques * u8 bytes[157]; 45*64e86f63SLuís Henriques * u8 sha256[SHA256_DIGEST_SIZE]; 46*64e86f63SLuís Henriques * }; // 180 bytes => 240 bytes base64-encoded, which is <= NAME_MAX (255) 47*64e86f63SLuís Henriques * 48*64e86f63SLuís Henriques * (240 bytes is the maximum size allowed for snapshot names to take into 49*64e86f63SLuís Henriques * account the format: '_<SNAPSHOT-NAME>_<INODE-NUMBER>'.) 50*64e86f63SLuís Henriques * 51*64e86f63SLuís Henriques * Note that for long names that end up having their tail portion hashed, we 52*64e86f63SLuís Henriques * must also store the full encrypted name (in the dentry's alternate_name 53*64e86f63SLuís Henriques * field). 54*64e86f63SLuís Henriques */ 55*64e86f63SLuís Henriques #define CEPH_NOHASH_NAME_MAX (180 - SHA256_DIGEST_SIZE) 56*64e86f63SLuís Henriques 57*64e86f63SLuís Henriques #define CEPH_BASE64_CHARS(nbytes) DIV_ROUND_UP((nbytes) * 4, 3) 58*64e86f63SLuís Henriques 59*64e86f63SLuís Henriques int ceph_base64_encode(const u8 *src, int srclen, char *dst); 60*64e86f63SLuís Henriques int ceph_base64_decode(const char *src, int srclen, u8 *dst); 61*64e86f63SLuís Henriques 622d332d5bSJeff Layton void ceph_fscrypt_set_ops(struct super_block *sb); 632d332d5bSJeff Layton 646b5717bdSJeff Layton void ceph_fscrypt_free_dummy_policy(struct ceph_fs_client *fsc); 656b5717bdSJeff Layton 666b5717bdSJeff Layton int ceph_fscrypt_prepare_context(struct inode *dir, struct inode *inode, 676b5717bdSJeff Layton struct ceph_acl_sec_ctx *as); 686b5717bdSJeff Layton void ceph_fscrypt_as_ctx_to_req(struct ceph_mds_request *req, 696b5717bdSJeff Layton struct ceph_acl_sec_ctx *as); 706b5717bdSJeff Layton 712d332d5bSJeff Layton #else /* CONFIG_FS_ENCRYPTION */ 722d332d5bSJeff Layton 732d332d5bSJeff Layton static inline void ceph_fscrypt_set_ops(struct super_block *sb) 742d332d5bSJeff Layton { 752d332d5bSJeff Layton } 762d332d5bSJeff Layton 776b5717bdSJeff Layton static inline void ceph_fscrypt_free_dummy_policy(struct ceph_fs_client *fsc) 786b5717bdSJeff Layton { 796b5717bdSJeff Layton } 806b5717bdSJeff Layton 816b5717bdSJeff Layton static inline int ceph_fscrypt_prepare_context(struct inode *dir, 826b5717bdSJeff Layton struct inode *inode, 836b5717bdSJeff Layton struct ceph_acl_sec_ctx *as) 846b5717bdSJeff Layton { 856b5717bdSJeff Layton if (IS_ENCRYPTED(dir)) 866b5717bdSJeff Layton return -EOPNOTSUPP; 876b5717bdSJeff Layton return 0; 886b5717bdSJeff Layton } 896b5717bdSJeff Layton 906b5717bdSJeff Layton static inline void ceph_fscrypt_as_ctx_to_req(struct ceph_mds_request *req, 916b5717bdSJeff Layton struct ceph_acl_sec_ctx *as_ctx) 926b5717bdSJeff Layton { 936b5717bdSJeff Layton } 942d332d5bSJeff Layton #endif /* CONFIG_FS_ENCRYPTION */ 952d332d5bSJeff Layton 962d332d5bSJeff Layton #endif 97