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 1294af0470SJeff Layton #define CEPH_FSCRYPT_BLOCK_SHIFT 12 1394af0470SJeff Layton #define CEPH_FSCRYPT_BLOCK_SIZE (_AC(1, UL) << CEPH_FSCRYPT_BLOCK_SHIFT) 1494af0470SJeff Layton #define CEPH_FSCRYPT_BLOCK_MASK (~(CEPH_FSCRYPT_BLOCK_SIZE-1)) 1594af0470SJeff Layton 166b5717bdSJeff Layton struct ceph_fs_client; 176b5717bdSJeff Layton struct ceph_acl_sec_ctx; 186b5717bdSJeff Layton struct ceph_mds_request; 196b5717bdSJeff Layton 20457117f0SJeff Layton struct ceph_fname { 21457117f0SJeff Layton struct inode *dir; 22457117f0SJeff Layton char *name; // b64 encoded, possibly hashed 23457117f0SJeff Layton unsigned char *ctext; // binary crypttext (if any) 24457117f0SJeff Layton u32 name_len; // length of name buffer 25457117f0SJeff Layton u32 ctext_len; // length of crypttext 26af9ffa6dSXiubo Li bool no_copy; 27457117f0SJeff Layton }; 28457117f0SJeff Layton 292d332d5bSJeff Layton struct ceph_fscrypt_auth { 302d332d5bSJeff Layton __le32 cfa_version; 312d332d5bSJeff Layton __le32 cfa_blob_len; 322d332d5bSJeff Layton u8 cfa_blob[FSCRYPT_SET_CONTEXT_MAX_SIZE]; 332d332d5bSJeff Layton } __packed; 342d332d5bSJeff Layton 352d332d5bSJeff Layton #define CEPH_FSCRYPT_AUTH_VERSION 1 362d332d5bSJeff Layton static inline u32 ceph_fscrypt_auth_len(struct ceph_fscrypt_auth *fa) 372d332d5bSJeff Layton { 382d332d5bSJeff Layton u32 ctxsize = le32_to_cpu(fa->cfa_blob_len); 392d332d5bSJeff Layton 402d332d5bSJeff Layton return offsetof(struct ceph_fscrypt_auth, cfa_blob) + ctxsize; 412d332d5bSJeff Layton } 422d332d5bSJeff Layton 432d332d5bSJeff Layton #ifdef CONFIG_FS_ENCRYPTION 4464e86f63SLuís Henriques /* 4564e86f63SLuís Henriques * We want to encrypt filenames when creating them, but the encrypted 4664e86f63SLuís Henriques * versions of those names may have illegal characters in them. To mitigate 4764e86f63SLuís Henriques * that, we base64 encode them, but that gives us a result that can exceed 4864e86f63SLuís Henriques * NAME_MAX. 4964e86f63SLuís Henriques * 5064e86f63SLuís Henriques * Follow a similar scheme to fscrypt itself, and cap the filename to a 5164e86f63SLuís Henriques * smaller size. If the ciphertext name is longer than the value below, then 5264e86f63SLuís Henriques * sha256 hash the remaining bytes. 5364e86f63SLuís Henriques * 5464e86f63SLuís Henriques * For the fscrypt_nokey_name struct the dirhash[2] member is useless in ceph 5564e86f63SLuís Henriques * so the corresponding struct will be: 5664e86f63SLuís Henriques * 5764e86f63SLuís Henriques * struct fscrypt_ceph_nokey_name { 5864e86f63SLuís Henriques * u8 bytes[157]; 5964e86f63SLuís Henriques * u8 sha256[SHA256_DIGEST_SIZE]; 6064e86f63SLuís Henriques * }; // 180 bytes => 240 bytes base64-encoded, which is <= NAME_MAX (255) 6164e86f63SLuís Henriques * 6264e86f63SLuís Henriques * (240 bytes is the maximum size allowed for snapshot names to take into 6364e86f63SLuís Henriques * account the format: '_<SNAPSHOT-NAME>_<INODE-NUMBER>'.) 6464e86f63SLuís Henriques * 6564e86f63SLuís Henriques * Note that for long names that end up having their tail portion hashed, we 6664e86f63SLuís Henriques * must also store the full encrypted name (in the dentry's alternate_name 6764e86f63SLuís Henriques * field). 6864e86f63SLuís Henriques */ 6964e86f63SLuís Henriques #define CEPH_NOHASH_NAME_MAX (180 - SHA256_DIGEST_SIZE) 7064e86f63SLuís Henriques 7164e86f63SLuís Henriques #define CEPH_BASE64_CHARS(nbytes) DIV_ROUND_UP((nbytes) * 4, 3) 7264e86f63SLuís Henriques 7364e86f63SLuís Henriques int ceph_base64_encode(const u8 *src, int srclen, char *dst); 7464e86f63SLuís Henriques int ceph_base64_decode(const char *src, int srclen, u8 *dst); 7564e86f63SLuís Henriques 762d332d5bSJeff Layton void ceph_fscrypt_set_ops(struct super_block *sb); 772d332d5bSJeff Layton 786b5717bdSJeff Layton void ceph_fscrypt_free_dummy_policy(struct ceph_fs_client *fsc); 796b5717bdSJeff Layton 806b5717bdSJeff Layton int ceph_fscrypt_prepare_context(struct inode *dir, struct inode *inode, 816b5717bdSJeff Layton struct ceph_acl_sec_ctx *as); 826b5717bdSJeff Layton void ceph_fscrypt_as_ctx_to_req(struct ceph_mds_request *req, 836b5717bdSJeff Layton struct ceph_acl_sec_ctx *as); 84af9ffa6dSXiubo Li int ceph_encode_encrypted_dname(const struct inode *parent, 85af9ffa6dSXiubo Li struct qstr *d_name, char *buf); 863fd945a7SJeff Layton int ceph_encode_encrypted_fname(const struct inode *parent, 873fd945a7SJeff Layton struct dentry *dentry, char *buf); 886b5717bdSJeff Layton 89457117f0SJeff Layton static inline int ceph_fname_alloc_buffer(struct inode *parent, 90457117f0SJeff Layton struct fscrypt_str *fname) 91457117f0SJeff Layton { 92457117f0SJeff Layton if (!IS_ENCRYPTED(parent)) 93457117f0SJeff Layton return 0; 94457117f0SJeff Layton return fscrypt_fname_alloc_buffer(NAME_MAX, fname); 95457117f0SJeff Layton } 96457117f0SJeff Layton 97457117f0SJeff Layton static inline void ceph_fname_free_buffer(struct inode *parent, 98457117f0SJeff Layton struct fscrypt_str *fname) 99457117f0SJeff Layton { 100457117f0SJeff Layton if (IS_ENCRYPTED(parent)) 101457117f0SJeff Layton fscrypt_fname_free_buffer(fname); 102457117f0SJeff Layton } 103457117f0SJeff Layton 104457117f0SJeff Layton int ceph_fname_to_usr(const struct ceph_fname *fname, struct fscrypt_str *tname, 105457117f0SJeff Layton struct fscrypt_str *oname, bool *is_nokey); 10614e034a6SLuís Henriques int ceph_fscrypt_prepare_readdir(struct inode *dir); 107457117f0SJeff Layton 108*77cdb7e1SJeff Layton static inline unsigned int ceph_fscrypt_blocks(u64 off, u64 len) 109*77cdb7e1SJeff Layton { 110*77cdb7e1SJeff Layton /* crypto blocks cannot span more than one page */ 111*77cdb7e1SJeff Layton BUILD_BUG_ON(CEPH_FSCRYPT_BLOCK_SHIFT > PAGE_SHIFT); 112*77cdb7e1SJeff Layton 113*77cdb7e1SJeff Layton return ((off+len+CEPH_FSCRYPT_BLOCK_SIZE-1) >> CEPH_FSCRYPT_BLOCK_SHIFT) - 114*77cdb7e1SJeff Layton (off >> CEPH_FSCRYPT_BLOCK_SHIFT); 115*77cdb7e1SJeff Layton } 116*77cdb7e1SJeff Layton 117*77cdb7e1SJeff Layton /* 118*77cdb7e1SJeff Layton * If we have an encrypted inode then we must adjust the offset and 119*77cdb7e1SJeff Layton * range of the on-the-wire read to cover an entire encryption block. 120*77cdb7e1SJeff Layton * The copy will be done using the original offset and length, after 121*77cdb7e1SJeff Layton * we've decrypted the result. 122*77cdb7e1SJeff Layton */ 123*77cdb7e1SJeff Layton static inline void ceph_fscrypt_adjust_off_and_len(struct inode *inode, 124*77cdb7e1SJeff Layton u64 *off, u64 *len) 125*77cdb7e1SJeff Layton { 126*77cdb7e1SJeff Layton if (IS_ENCRYPTED(inode)) { 127*77cdb7e1SJeff Layton *len = ceph_fscrypt_blocks(*off, *len) * CEPH_FSCRYPT_BLOCK_SIZE; 128*77cdb7e1SJeff Layton *off &= CEPH_FSCRYPT_BLOCK_MASK; 129*77cdb7e1SJeff Layton } 130*77cdb7e1SJeff Layton } 131*77cdb7e1SJeff Layton 132*77cdb7e1SJeff Layton int ceph_fscrypt_decrypt_block_inplace(const struct inode *inode, 133*77cdb7e1SJeff Layton struct page *page, unsigned int len, 134*77cdb7e1SJeff Layton unsigned int offs, u64 lblk_num); 135*77cdb7e1SJeff Layton int ceph_fscrypt_encrypt_block_inplace(const struct inode *inode, 136*77cdb7e1SJeff Layton struct page *page, unsigned int len, 137*77cdb7e1SJeff Layton unsigned int offs, u64 lblk_num, 138*77cdb7e1SJeff Layton gfp_t gfp_flags); 139*77cdb7e1SJeff Layton int ceph_fscrypt_decrypt_pages(struct inode *inode, struct page **page, 140*77cdb7e1SJeff Layton u64 off, int len); 141*77cdb7e1SJeff Layton int ceph_fscrypt_decrypt_extents(struct inode *inode, struct page **page, 142*77cdb7e1SJeff Layton u64 off, struct ceph_sparse_extent *map, 143*77cdb7e1SJeff Layton u32 ext_cnt); 144*77cdb7e1SJeff Layton int ceph_fscrypt_encrypt_pages(struct inode *inode, struct page **page, u64 off, 145*77cdb7e1SJeff Layton int len, gfp_t gfp); 1462d332d5bSJeff Layton #else /* CONFIG_FS_ENCRYPTION */ 1472d332d5bSJeff Layton 1482d332d5bSJeff Layton static inline void ceph_fscrypt_set_ops(struct super_block *sb) 1492d332d5bSJeff Layton { 1502d332d5bSJeff Layton } 1512d332d5bSJeff Layton 1526b5717bdSJeff Layton static inline void ceph_fscrypt_free_dummy_policy(struct ceph_fs_client *fsc) 1536b5717bdSJeff Layton { 1546b5717bdSJeff Layton } 1556b5717bdSJeff Layton 1566b5717bdSJeff Layton static inline int ceph_fscrypt_prepare_context(struct inode *dir, 1576b5717bdSJeff Layton struct inode *inode, 1586b5717bdSJeff Layton struct ceph_acl_sec_ctx *as) 1596b5717bdSJeff Layton { 1606b5717bdSJeff Layton if (IS_ENCRYPTED(dir)) 1616b5717bdSJeff Layton return -EOPNOTSUPP; 1626b5717bdSJeff Layton return 0; 1636b5717bdSJeff Layton } 1646b5717bdSJeff Layton 1656b5717bdSJeff Layton static inline void ceph_fscrypt_as_ctx_to_req(struct ceph_mds_request *req, 1666b5717bdSJeff Layton struct ceph_acl_sec_ctx *as_ctx) 1676b5717bdSJeff Layton { 1686b5717bdSJeff Layton } 1693fd945a7SJeff Layton 170af9ffa6dSXiubo Li static inline int ceph_encode_encrypted_dname(const struct inode *parent, 171af9ffa6dSXiubo Li struct qstr *d_name, char *buf) 172af9ffa6dSXiubo Li { 173af9ffa6dSXiubo Li memcpy(buf, d_name->name, d_name->len); 174af9ffa6dSXiubo Li return d_name->len; 175af9ffa6dSXiubo Li } 176af9ffa6dSXiubo Li 1773fd945a7SJeff Layton static inline int ceph_encode_encrypted_fname(const struct inode *parent, 1783fd945a7SJeff Layton struct dentry *dentry, char *buf) 1793fd945a7SJeff Layton { 1803fd945a7SJeff Layton return -EOPNOTSUPP; 1813fd945a7SJeff Layton } 182457117f0SJeff Layton 183457117f0SJeff Layton static inline int ceph_fname_alloc_buffer(struct inode *parent, 184457117f0SJeff Layton struct fscrypt_str *fname) 185457117f0SJeff Layton { 186457117f0SJeff Layton return 0; 187457117f0SJeff Layton } 188457117f0SJeff Layton 189457117f0SJeff Layton static inline void ceph_fname_free_buffer(struct inode *parent, 190457117f0SJeff Layton struct fscrypt_str *fname) 191457117f0SJeff Layton { 192457117f0SJeff Layton } 193457117f0SJeff Layton 194457117f0SJeff Layton static inline int ceph_fname_to_usr(const struct ceph_fname *fname, 195457117f0SJeff Layton struct fscrypt_str *tname, 196457117f0SJeff Layton struct fscrypt_str *oname, bool *is_nokey) 197457117f0SJeff Layton { 198457117f0SJeff Layton oname->name = fname->name; 199457117f0SJeff Layton oname->len = fname->name_len; 200457117f0SJeff Layton return 0; 201457117f0SJeff Layton } 20214e034a6SLuís Henriques 20314e034a6SLuís Henriques static inline int ceph_fscrypt_prepare_readdir(struct inode *dir) 20414e034a6SLuís Henriques { 20514e034a6SLuís Henriques return 0; 20614e034a6SLuís Henriques } 207*77cdb7e1SJeff Layton 208*77cdb7e1SJeff Layton static inline void ceph_fscrypt_adjust_off_and_len(struct inode *inode, 209*77cdb7e1SJeff Layton u64 *off, u64 *len) 210*77cdb7e1SJeff Layton { 211*77cdb7e1SJeff Layton } 212*77cdb7e1SJeff Layton 213*77cdb7e1SJeff Layton static inline int ceph_fscrypt_decrypt_block_inplace(const struct inode *inode, 214*77cdb7e1SJeff Layton struct page *page, unsigned int len, 215*77cdb7e1SJeff Layton unsigned int offs, u64 lblk_num) 216*77cdb7e1SJeff Layton { 217*77cdb7e1SJeff Layton return 0; 218*77cdb7e1SJeff Layton } 219*77cdb7e1SJeff Layton 220*77cdb7e1SJeff Layton static inline int ceph_fscrypt_encrypt_block_inplace(const struct inode *inode, 221*77cdb7e1SJeff Layton struct page *page, unsigned int len, 222*77cdb7e1SJeff Layton unsigned int offs, u64 lblk_num, 223*77cdb7e1SJeff Layton gfp_t gfp_flags) 224*77cdb7e1SJeff Layton { 225*77cdb7e1SJeff Layton return 0; 226*77cdb7e1SJeff Layton } 227*77cdb7e1SJeff Layton 228*77cdb7e1SJeff Layton static inline int ceph_fscrypt_decrypt_pages(struct inode *inode, 229*77cdb7e1SJeff Layton struct page **page, u64 off, 230*77cdb7e1SJeff Layton int len) 231*77cdb7e1SJeff Layton { 232*77cdb7e1SJeff Layton return 0; 233*77cdb7e1SJeff Layton } 234*77cdb7e1SJeff Layton 235*77cdb7e1SJeff Layton static inline int ceph_fscrypt_decrypt_extents(struct inode *inode, 236*77cdb7e1SJeff Layton struct page **page, u64 off, 237*77cdb7e1SJeff Layton struct ceph_sparse_extent *map, 238*77cdb7e1SJeff Layton u32 ext_cnt) 239*77cdb7e1SJeff Layton { 240*77cdb7e1SJeff Layton return 0; 241*77cdb7e1SJeff Layton } 242*77cdb7e1SJeff Layton 243*77cdb7e1SJeff Layton static inline int ceph_fscrypt_encrypt_pages(struct inode *inode, 244*77cdb7e1SJeff Layton struct page **page, u64 off, 245*77cdb7e1SJeff Layton int len, gfp_t gfp) 246*77cdb7e1SJeff Layton { 247*77cdb7e1SJeff Layton return 0; 248*77cdb7e1SJeff Layton } 2492d332d5bSJeff Layton #endif /* CONFIG_FS_ENCRYPTION */ 2502d332d5bSJeff Layton 2512d332d5bSJeff Layton #endif 252