File Index
Files and directories
Sign in
FILE

crypto.h

File preview with syntax highlighting.

linux-6.19.14/fs/ceph/crypto.h C
  1/* SPDX-License-Identifier: GPL-2.0 */
  2/*
  3 * Ceph fscrypt functionality
  4 */
  5
  6#ifndef _CEPH_CRYPTO_H
  7#define _CEPH_CRYPTO_H
  8
  9#include <crypto/sha2.h>
 10#include <linux/fscrypt.h>
 11#include <linux/base64.h>
 12
 13#define CEPH_FSCRYPT_BLOCK_SHIFT   12
 14#define CEPH_FSCRYPT_BLOCK_SIZE    (_AC(1, UL) << CEPH_FSCRYPT_BLOCK_SHIFT)
 15#define CEPH_FSCRYPT_BLOCK_MASK	   (~(CEPH_FSCRYPT_BLOCK_SIZE-1))
 16
 17struct ceph_fs_client;
 18struct ceph_acl_sec_ctx;
 19struct ceph_mds_request;
 20
 21struct ceph_fname {
 22	struct inode	*dir;
 23	char		*name;		// b64 encoded, possibly hashed
 24	unsigned char	*ctext;		// binary crypttext (if any)
 25	u32		name_len;	// length of name buffer
 26	u32		ctext_len;	// length of crypttext
 27	bool		no_copy;
 28};
 29
 30/*
 31 * Header for the encrypted file when truncating the size, this
 32 * will be sent to MDS, and the MDS will update the encrypted
 33 * last block and then truncate the size.
 34 */
 35struct ceph_fscrypt_truncate_size_header {
 36	__u8  ver;
 37	__u8  compat;
 38
 39	/*
 40	 * It will be sizeof(assert_ver + file_offset + block_size)
 41	 * if the last block is empty when it's located in a file
 42	 * hole. Or the data_len will plus CEPH_FSCRYPT_BLOCK_SIZE.
 43	 */
 44	__le32 data_len;
 45
 46	__le64 change_attr;
 47	__le64 file_offset;
 48	__le32 block_size;
 49} __packed;
 50
 51struct ceph_fscrypt_auth {
 52	__le32	cfa_version;
 53	__le32	cfa_blob_len;
 54	u8	cfa_blob[FSCRYPT_SET_CONTEXT_MAX_SIZE];
 55} __packed;
 56
 57#define CEPH_FSCRYPT_AUTH_VERSION	1
 58static inline u32 ceph_fscrypt_auth_len(struct ceph_fscrypt_auth *fa)
 59{
 60	u32 ctxsize = le32_to_cpu(fa->cfa_blob_len);
 61
 62	return offsetof(struct ceph_fscrypt_auth, cfa_blob) + ctxsize;
 63}
 64
 65#ifdef CONFIG_FS_ENCRYPTION
 66/*
 67 * We want to encrypt filenames when creating them, but the encrypted
 68 * versions of those names may have illegal characters in them. To mitigate
 69 * that, we base64 encode them, but that gives us a result that can exceed
 70 * NAME_MAX.
 71 *
 72 * Follow a similar scheme to fscrypt itself, and cap the filename to a
 73 * smaller size. If the ciphertext name is longer than the value below, then
 74 * sha256 hash the remaining bytes.
 75 *
 76 * For the fscrypt_nokey_name struct the dirhash[2] member is useless in ceph
 77 * so the corresponding struct will be:
 78 *
 79 * struct fscrypt_ceph_nokey_name {
 80 *	u8 bytes[157];
 81 *	u8 sha256[SHA256_DIGEST_SIZE];
 82 * }; // 180 bytes => 240 bytes base64-encoded, which is <= NAME_MAX (255)
 83 *
 84 * (240 bytes is the maximum size allowed for snapshot names to take into
 85 *  account the format: '_<SNAPSHOT-NAME>_<INODE-NUMBER>'.)
 86 *
 87 * Note that for long names that end up having their tail portion hashed, we
 88 * must also store the full encrypted name (in the dentry's alternate_name
 89 * field).
 90 */
 91#define CEPH_NOHASH_NAME_MAX (180 - SHA256_DIGEST_SIZE)
 92
 93void ceph_fscrypt_set_ops(struct super_block *sb);
 94
 95void ceph_fscrypt_free_dummy_policy(struct ceph_fs_client *fsc);
 96
 97int ceph_fscrypt_prepare_context(struct inode *dir, struct inode *inode,
 98				 struct ceph_acl_sec_ctx *as);
 99void ceph_fscrypt_as_ctx_to_req(struct ceph_mds_request *req,
100				struct ceph_acl_sec_ctx *as);
101int ceph_encode_encrypted_dname(struct inode *parent, char *buf, int len);
102
103static inline int ceph_fname_alloc_buffer(struct inode *parent,
104					  struct fscrypt_str *fname)
105{
106	if (!IS_ENCRYPTED(parent))
107		return 0;
108	return fscrypt_fname_alloc_buffer(NAME_MAX, fname);
109}
110
111static inline void ceph_fname_free_buffer(struct inode *parent,
112					  struct fscrypt_str *fname)
113{
114	if (IS_ENCRYPTED(parent))
115		fscrypt_fname_free_buffer(fname);
116}
117
118int ceph_fname_to_usr(const struct ceph_fname *fname, struct fscrypt_str *tname,
119		      struct fscrypt_str *oname, bool *is_nokey);
120int ceph_fscrypt_prepare_readdir(struct inode *dir);
121
122static inline unsigned int ceph_fscrypt_blocks(u64 off, u64 len)
123{
124	/* crypto blocks cannot span more than one page */
125	BUILD_BUG_ON(CEPH_FSCRYPT_BLOCK_SHIFT > PAGE_SHIFT);
126
127	return ((off+len+CEPH_FSCRYPT_BLOCK_SIZE-1) >> CEPH_FSCRYPT_BLOCK_SHIFT) -
128		(off >> CEPH_FSCRYPT_BLOCK_SHIFT);
129}
130
131/*
132 * If we have an encrypted inode then we must adjust the offset and
133 * range of the on-the-wire read to cover an entire encryption block.
134 * The copy will be done using the original offset and length, after
135 * we've decrypted the result.
136 */
137static inline void ceph_fscrypt_adjust_off_and_len(struct inode *inode,
138						   u64 *off, u64 *len)
139{
140	if (IS_ENCRYPTED(inode)) {
141		*len = ceph_fscrypt_blocks(*off, *len) * CEPH_FSCRYPT_BLOCK_SIZE;
142		*off &= CEPH_FSCRYPT_BLOCK_MASK;
143	}
144}
145
146int ceph_fscrypt_decrypt_block_inplace(const struct inode *inode,
147				  struct page *page, unsigned int len,
148				  unsigned int offs, u64 lblk_num);
149int ceph_fscrypt_encrypt_block_inplace(const struct inode *inode,
150				  struct page *page, unsigned int len,
151				  unsigned int offs, u64 lblk_num);
152int ceph_fscrypt_decrypt_pages(struct inode *inode, struct page **page,
153			       u64 off, int len);
154int ceph_fscrypt_decrypt_extents(struct inode *inode, struct page **page,
155				 u64 off, struct ceph_sparse_extent *map,
156				 u32 ext_cnt);
157int ceph_fscrypt_encrypt_pages(struct inode *inode, struct page **page, u64 off,
158			       int len);
159
160static inline struct page *ceph_fscrypt_pagecache_page(struct page *page)
161{
162	return fscrypt_is_bounce_page(page) ? fscrypt_pagecache_page(page) : page;
163}
164
165#else /* CONFIG_FS_ENCRYPTION */
166
167static inline void ceph_fscrypt_set_ops(struct super_block *sb)
168{
169}
170
171static inline void ceph_fscrypt_free_dummy_policy(struct ceph_fs_client *fsc)
172{
173}
174
175static inline int ceph_fscrypt_prepare_context(struct inode *dir,
176					       struct inode *inode,
177					       struct ceph_acl_sec_ctx *as)
178{
179	if (IS_ENCRYPTED(dir))
180		return -EOPNOTSUPP;
181	return 0;
182}
183
184static inline void ceph_fscrypt_as_ctx_to_req(struct ceph_mds_request *req,
185						struct ceph_acl_sec_ctx *as_ctx)
186{
187}
188
189static inline int ceph_encode_encrypted_dname(struct inode *parent, char *buf,
190					      int len)
191{
192	return len;
193}
194
195static inline int ceph_fname_alloc_buffer(struct inode *parent,
196					  struct fscrypt_str *fname)
197{
198	return 0;
199}
200
201static inline void ceph_fname_free_buffer(struct inode *parent,
202					  struct fscrypt_str *fname)
203{
204}
205
206static inline int ceph_fname_to_usr(const struct ceph_fname *fname,
207				    struct fscrypt_str *tname,
208				    struct fscrypt_str *oname, bool *is_nokey)
209{
210	oname->name = fname->name;
211	oname->len = fname->name_len;
212	return 0;
213}
214
215static inline int ceph_fscrypt_prepare_readdir(struct inode *dir)
216{
217	return 0;
218}
219
220static inline void ceph_fscrypt_adjust_off_and_len(struct inode *inode,
221						   u64 *off, u64 *len)
222{
223}
224
225static inline int ceph_fscrypt_decrypt_block_inplace(const struct inode *inode,
226					  struct page *page, unsigned int len,
227					  unsigned int offs, u64 lblk_num)
228{
229	return 0;
230}
231
232static inline int ceph_fscrypt_encrypt_block_inplace(const struct inode *inode,
233					  struct page *page, unsigned int len,
234					  unsigned int offs, u64 lblk_num)
235{
236	return 0;
237}
238
239static inline int ceph_fscrypt_decrypt_pages(struct inode *inode,
240					     struct page **page, u64 off,
241					     int len)
242{
243	return 0;
244}
245
246static inline int ceph_fscrypt_decrypt_extents(struct inode *inode,
247					       struct page **page, u64 off,
248					       struct ceph_sparse_extent *map,
249					       u32 ext_cnt)
250{
251	return 0;
252}
253
254static inline int ceph_fscrypt_encrypt_pages(struct inode *inode,
255					     struct page **page, u64 off,
256					     int len)
257{
258	return 0;
259}
260
261static inline struct page *ceph_fscrypt_pagecache_page(struct page *page)
262{
263	return page;
264}
265#endif /* CONFIG_FS_ENCRYPTION */
266
267static inline loff_t ceph_fscrypt_page_offset(struct page *page)
268{
269	return page_offset(ceph_fscrypt_pagecache_page(page));
270}
271
272#endif /* _CEPH_CRYPTO_H */
~/ Read-only file preview.