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 29*5c64737dSXiubo Li /* 30*5c64737dSXiubo Li * Header for the crypted file when truncating the size, this 31*5c64737dSXiubo Li * will be sent to MDS, and the MDS will update the encrypted 32*5c64737dSXiubo Li * last block and then truncate the size. 33*5c64737dSXiubo Li */ 34*5c64737dSXiubo Li struct ceph_fscrypt_truncate_size_header { 35*5c64737dSXiubo Li __u8 ver; 36*5c64737dSXiubo Li __u8 compat; 37*5c64737dSXiubo Li 38*5c64737dSXiubo Li /* 39*5c64737dSXiubo Li * It will be sizeof(assert_ver + file_offset + block_size) 40*5c64737dSXiubo Li * if the last block is empty when it's located in a file 41*5c64737dSXiubo Li * hole. Or the data_len will plus CEPH_FSCRYPT_BLOCK_SIZE. 42*5c64737dSXiubo Li */ 43*5c64737dSXiubo Li __le32 data_len; 44*5c64737dSXiubo Li 45*5c64737dSXiubo Li __le64 change_attr; 46*5c64737dSXiubo Li __le64 file_offset; 47*5c64737dSXiubo Li __le32 block_size; 48*5c64737dSXiubo Li } __packed; 49*5c64737dSXiubo Li 502d332d5bSJeff Layton struct ceph_fscrypt_auth { 512d332d5bSJeff Layton __le32 cfa_version; 522d332d5bSJeff Layton __le32 cfa_blob_len; 532d332d5bSJeff Layton u8 cfa_blob[FSCRYPT_SET_CONTEXT_MAX_SIZE]; 542d332d5bSJeff Layton } __packed; 552d332d5bSJeff Layton 562d332d5bSJeff Layton #define CEPH_FSCRYPT_AUTH_VERSION 1 572d332d5bSJeff Layton static inline u32 ceph_fscrypt_auth_len(struct ceph_fscrypt_auth *fa) 582d332d5bSJeff Layton { 592d332d5bSJeff Layton u32 ctxsize = le32_to_cpu(fa->cfa_blob_len); 602d332d5bSJeff Layton 612d332d5bSJeff Layton return offsetof(struct ceph_fscrypt_auth, cfa_blob) + ctxsize; 622d332d5bSJeff Layton } 632d332d5bSJeff Layton 642d332d5bSJeff Layton #ifdef CONFIG_FS_ENCRYPTION 6564e86f63SLuís Henriques /* 6664e86f63SLuís Henriques * We want to encrypt filenames when creating them, but the encrypted 6764e86f63SLuís Henriques * versions of those names may have illegal characters in them. To mitigate 6864e86f63SLuís Henriques * that, we base64 encode them, but that gives us a result that can exceed 6964e86f63SLuís Henriques * NAME_MAX. 7064e86f63SLuís Henriques * 7164e86f63SLuís Henriques * Follow a similar scheme to fscrypt itself, and cap the filename to a 7264e86f63SLuís Henriques * smaller size. If the ciphertext name is longer than the value below, then 7364e86f63SLuís Henriques * sha256 hash the remaining bytes. 7464e86f63SLuís Henriques * 7564e86f63SLuís Henriques * For the fscrypt_nokey_name struct the dirhash[2] member is useless in ceph 7664e86f63SLuís Henriques * so the corresponding struct will be: 7764e86f63SLuís Henriques * 7864e86f63SLuís Henriques * struct fscrypt_ceph_nokey_name { 7964e86f63SLuís Henriques * u8 bytes[157]; 8064e86f63SLuís Henriques * u8 sha256[SHA256_DIGEST_SIZE]; 8164e86f63SLuís Henriques * }; // 180 bytes => 240 bytes base64-encoded, which is <= NAME_MAX (255) 8264e86f63SLuís Henriques * 8364e86f63SLuís Henriques * (240 bytes is the maximum size allowed for snapshot names to take into 8464e86f63SLuís Henriques * account the format: '_<SNAPSHOT-NAME>_<INODE-NUMBER>'.) 8564e86f63SLuís Henriques * 8664e86f63SLuís Henriques * Note that for long names that end up having their tail portion hashed, we 8764e86f63SLuís Henriques * must also store the full encrypted name (in the dentry's alternate_name 8864e86f63SLuís Henriques * field). 8964e86f63SLuís Henriques */ 9064e86f63SLuís Henriques #define CEPH_NOHASH_NAME_MAX (180 - SHA256_DIGEST_SIZE) 9164e86f63SLuís Henriques 9264e86f63SLuís Henriques #define CEPH_BASE64_CHARS(nbytes) DIV_ROUND_UP((nbytes) * 4, 3) 9364e86f63SLuís Henriques 9464e86f63SLuís Henriques int ceph_base64_encode(const u8 *src, int srclen, char *dst); 9564e86f63SLuís Henriques int ceph_base64_decode(const char *src, int srclen, u8 *dst); 9664e86f63SLuís Henriques 972d332d5bSJeff Layton void ceph_fscrypt_set_ops(struct super_block *sb); 982d332d5bSJeff Layton 996b5717bdSJeff Layton void ceph_fscrypt_free_dummy_policy(struct ceph_fs_client *fsc); 1006b5717bdSJeff Layton 1016b5717bdSJeff Layton int ceph_fscrypt_prepare_context(struct inode *dir, struct inode *inode, 1026b5717bdSJeff Layton struct ceph_acl_sec_ctx *as); 1036b5717bdSJeff Layton void ceph_fscrypt_as_ctx_to_req(struct ceph_mds_request *req, 1046b5717bdSJeff Layton struct ceph_acl_sec_ctx *as); 105af9ffa6dSXiubo Li int ceph_encode_encrypted_dname(const struct inode *parent, 106af9ffa6dSXiubo Li struct qstr *d_name, char *buf); 1073fd945a7SJeff Layton int ceph_encode_encrypted_fname(const struct inode *parent, 1083fd945a7SJeff Layton struct dentry *dentry, char *buf); 1096b5717bdSJeff Layton 110457117f0SJeff Layton static inline int ceph_fname_alloc_buffer(struct inode *parent, 111457117f0SJeff Layton struct fscrypt_str *fname) 112457117f0SJeff Layton { 113457117f0SJeff Layton if (!IS_ENCRYPTED(parent)) 114457117f0SJeff Layton return 0; 115457117f0SJeff Layton return fscrypt_fname_alloc_buffer(NAME_MAX, fname); 116457117f0SJeff Layton } 117457117f0SJeff Layton 118457117f0SJeff Layton static inline void ceph_fname_free_buffer(struct inode *parent, 119457117f0SJeff Layton struct fscrypt_str *fname) 120457117f0SJeff Layton { 121457117f0SJeff Layton if (IS_ENCRYPTED(parent)) 122457117f0SJeff Layton fscrypt_fname_free_buffer(fname); 123457117f0SJeff Layton } 124457117f0SJeff Layton 125457117f0SJeff Layton int ceph_fname_to_usr(const struct ceph_fname *fname, struct fscrypt_str *tname, 126457117f0SJeff Layton struct fscrypt_str *oname, bool *is_nokey); 12714e034a6SLuís Henriques int ceph_fscrypt_prepare_readdir(struct inode *dir); 128457117f0SJeff Layton 12977cdb7e1SJeff Layton static inline unsigned int ceph_fscrypt_blocks(u64 off, u64 len) 13077cdb7e1SJeff Layton { 13177cdb7e1SJeff Layton /* crypto blocks cannot span more than one page */ 13277cdb7e1SJeff Layton BUILD_BUG_ON(CEPH_FSCRYPT_BLOCK_SHIFT > PAGE_SHIFT); 13377cdb7e1SJeff Layton 13477cdb7e1SJeff Layton return ((off+len+CEPH_FSCRYPT_BLOCK_SIZE-1) >> CEPH_FSCRYPT_BLOCK_SHIFT) - 13577cdb7e1SJeff Layton (off >> CEPH_FSCRYPT_BLOCK_SHIFT); 13677cdb7e1SJeff Layton } 13777cdb7e1SJeff Layton 13877cdb7e1SJeff Layton /* 13977cdb7e1SJeff Layton * If we have an encrypted inode then we must adjust the offset and 14077cdb7e1SJeff Layton * range of the on-the-wire read to cover an entire encryption block. 14177cdb7e1SJeff Layton * The copy will be done using the original offset and length, after 14277cdb7e1SJeff Layton * we've decrypted the result. 14377cdb7e1SJeff Layton */ 14477cdb7e1SJeff Layton static inline void ceph_fscrypt_adjust_off_and_len(struct inode *inode, 14577cdb7e1SJeff Layton u64 *off, u64 *len) 14677cdb7e1SJeff Layton { 14777cdb7e1SJeff Layton if (IS_ENCRYPTED(inode)) { 14877cdb7e1SJeff Layton *len = ceph_fscrypt_blocks(*off, *len) * CEPH_FSCRYPT_BLOCK_SIZE; 14977cdb7e1SJeff Layton *off &= CEPH_FSCRYPT_BLOCK_MASK; 15077cdb7e1SJeff Layton } 15177cdb7e1SJeff Layton } 15277cdb7e1SJeff Layton 15377cdb7e1SJeff Layton int ceph_fscrypt_decrypt_block_inplace(const struct inode *inode, 15477cdb7e1SJeff Layton struct page *page, unsigned int len, 15577cdb7e1SJeff Layton unsigned int offs, u64 lblk_num); 15677cdb7e1SJeff Layton int ceph_fscrypt_encrypt_block_inplace(const struct inode *inode, 15777cdb7e1SJeff Layton struct page *page, unsigned int len, 15877cdb7e1SJeff Layton unsigned int offs, u64 lblk_num, 15977cdb7e1SJeff Layton gfp_t gfp_flags); 16077cdb7e1SJeff Layton int ceph_fscrypt_decrypt_pages(struct inode *inode, struct page **page, 16177cdb7e1SJeff Layton u64 off, int len); 16277cdb7e1SJeff Layton int ceph_fscrypt_decrypt_extents(struct inode *inode, struct page **page, 16377cdb7e1SJeff Layton u64 off, struct ceph_sparse_extent *map, 16477cdb7e1SJeff Layton u32 ext_cnt); 16577cdb7e1SJeff Layton int ceph_fscrypt_encrypt_pages(struct inode *inode, struct page **page, u64 off, 16677cdb7e1SJeff Layton int len, gfp_t gfp); 1672d332d5bSJeff Layton #else /* CONFIG_FS_ENCRYPTION */ 1682d332d5bSJeff Layton 1692d332d5bSJeff Layton static inline void ceph_fscrypt_set_ops(struct super_block *sb) 1702d332d5bSJeff Layton { 1712d332d5bSJeff Layton } 1722d332d5bSJeff Layton 1736b5717bdSJeff Layton static inline void ceph_fscrypt_free_dummy_policy(struct ceph_fs_client *fsc) 1746b5717bdSJeff Layton { 1756b5717bdSJeff Layton } 1766b5717bdSJeff Layton 1776b5717bdSJeff Layton static inline int ceph_fscrypt_prepare_context(struct inode *dir, 1786b5717bdSJeff Layton struct inode *inode, 1796b5717bdSJeff Layton struct ceph_acl_sec_ctx *as) 1806b5717bdSJeff Layton { 1816b5717bdSJeff Layton if (IS_ENCRYPTED(dir)) 1826b5717bdSJeff Layton return -EOPNOTSUPP; 1836b5717bdSJeff Layton return 0; 1846b5717bdSJeff Layton } 1856b5717bdSJeff Layton 1866b5717bdSJeff Layton static inline void ceph_fscrypt_as_ctx_to_req(struct ceph_mds_request *req, 1876b5717bdSJeff Layton struct ceph_acl_sec_ctx *as_ctx) 1886b5717bdSJeff Layton { 1896b5717bdSJeff Layton } 1903fd945a7SJeff Layton 191af9ffa6dSXiubo Li static inline int ceph_encode_encrypted_dname(const struct inode *parent, 192af9ffa6dSXiubo Li struct qstr *d_name, char *buf) 193af9ffa6dSXiubo Li { 194af9ffa6dSXiubo Li memcpy(buf, d_name->name, d_name->len); 195af9ffa6dSXiubo Li return d_name->len; 196af9ffa6dSXiubo Li } 197af9ffa6dSXiubo Li 1983fd945a7SJeff Layton static inline int ceph_encode_encrypted_fname(const struct inode *parent, 1993fd945a7SJeff Layton struct dentry *dentry, char *buf) 2003fd945a7SJeff Layton { 2013fd945a7SJeff Layton return -EOPNOTSUPP; 2023fd945a7SJeff Layton } 203457117f0SJeff Layton 204457117f0SJeff Layton static inline int ceph_fname_alloc_buffer(struct inode *parent, 205457117f0SJeff Layton struct fscrypt_str *fname) 206457117f0SJeff Layton { 207457117f0SJeff Layton return 0; 208457117f0SJeff Layton } 209457117f0SJeff Layton 210457117f0SJeff Layton static inline void ceph_fname_free_buffer(struct inode *parent, 211457117f0SJeff Layton struct fscrypt_str *fname) 212457117f0SJeff Layton { 213457117f0SJeff Layton } 214457117f0SJeff Layton 215457117f0SJeff Layton static inline int ceph_fname_to_usr(const struct ceph_fname *fname, 216457117f0SJeff Layton struct fscrypt_str *tname, 217457117f0SJeff Layton struct fscrypt_str *oname, bool *is_nokey) 218457117f0SJeff Layton { 219457117f0SJeff Layton oname->name = fname->name; 220457117f0SJeff Layton oname->len = fname->name_len; 221457117f0SJeff Layton return 0; 222457117f0SJeff Layton } 22314e034a6SLuís Henriques 22414e034a6SLuís Henriques static inline int ceph_fscrypt_prepare_readdir(struct inode *dir) 22514e034a6SLuís Henriques { 22614e034a6SLuís Henriques return 0; 22714e034a6SLuís Henriques } 22877cdb7e1SJeff Layton 22977cdb7e1SJeff Layton static inline void ceph_fscrypt_adjust_off_and_len(struct inode *inode, 23077cdb7e1SJeff Layton u64 *off, u64 *len) 23177cdb7e1SJeff Layton { 23277cdb7e1SJeff Layton } 23377cdb7e1SJeff Layton 23477cdb7e1SJeff Layton static inline int ceph_fscrypt_decrypt_block_inplace(const struct inode *inode, 23577cdb7e1SJeff Layton struct page *page, unsigned int len, 23677cdb7e1SJeff Layton unsigned int offs, u64 lblk_num) 23777cdb7e1SJeff Layton { 23877cdb7e1SJeff Layton return 0; 23977cdb7e1SJeff Layton } 24077cdb7e1SJeff Layton 24177cdb7e1SJeff Layton static inline int ceph_fscrypt_encrypt_block_inplace(const struct inode *inode, 24277cdb7e1SJeff Layton struct page *page, unsigned int len, 24377cdb7e1SJeff Layton unsigned int offs, u64 lblk_num, 24477cdb7e1SJeff Layton gfp_t gfp_flags) 24577cdb7e1SJeff Layton { 24677cdb7e1SJeff Layton return 0; 24777cdb7e1SJeff Layton } 24877cdb7e1SJeff Layton 24977cdb7e1SJeff Layton static inline int ceph_fscrypt_decrypt_pages(struct inode *inode, 25077cdb7e1SJeff Layton struct page **page, u64 off, 25177cdb7e1SJeff Layton int len) 25277cdb7e1SJeff Layton { 25377cdb7e1SJeff Layton return 0; 25477cdb7e1SJeff Layton } 25577cdb7e1SJeff Layton 25677cdb7e1SJeff Layton static inline int ceph_fscrypt_decrypt_extents(struct inode *inode, 25777cdb7e1SJeff Layton struct page **page, u64 off, 25877cdb7e1SJeff Layton struct ceph_sparse_extent *map, 25977cdb7e1SJeff Layton u32 ext_cnt) 26077cdb7e1SJeff Layton { 26177cdb7e1SJeff Layton return 0; 26277cdb7e1SJeff Layton } 26377cdb7e1SJeff Layton 26477cdb7e1SJeff Layton static inline int ceph_fscrypt_encrypt_pages(struct inode *inode, 26577cdb7e1SJeff Layton struct page **page, u64 off, 26677cdb7e1SJeff Layton int len, gfp_t gfp) 26777cdb7e1SJeff Layton { 26877cdb7e1SJeff Layton return 0; 26977cdb7e1SJeff Layton } 2702d332d5bSJeff Layton #endif /* CONFIG_FS_ENCRYPTION */ 2712d332d5bSJeff Layton 2722d332d5bSJeff Layton #endif 273