diff options
author | David Gstir <david@sigma-star.at> | 2016-12-06 17:53:55 -0500 |
---|---|---|
committer | Theodore Ts'o <tytso@mit.edu> | 2016-12-11 16:26:12 -0500 |
commit | 1400451f04f2ff28b658b92557495e5090914aee (patch) | |
tree | 2f88dd7754096cb2768a50450242cc1c878d91b9 /fs/crypto | |
parent | 9e532772b4e36888584efc7a9531143bd43355b3 (diff) |
fscrypt: Cleanup fscrypt_{decrypt,encrypt}_page()
- Improve documentation
- Add BUG_ON(len == 0) to avoid accidental switch of offs and len
parameters
- Improve variable names for readability
Signed-off-by: David Gstir <david@sigma-star.at>
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
Diffstat (limited to 'fs/crypto')
-rw-r--r-- | fs/crypto/crypto.c | 93 |
1 files changed, 52 insertions, 41 deletions
diff --git a/fs/crypto/crypto.c b/fs/crypto/crypto.c index f287f76cc906..8c104e712bb2 100644 --- a/fs/crypto/crypto.c +++ b/fs/crypto/crypto.c | |||
@@ -147,9 +147,9 @@ typedef enum { | |||
147 | } fscrypt_direction_t; | 147 | } fscrypt_direction_t; |
148 | 148 | ||
149 | static int do_page_crypto(const struct inode *inode, | 149 | static int do_page_crypto(const struct inode *inode, |
150 | fscrypt_direction_t rw, pgoff_t index, | 150 | fscrypt_direction_t rw, u64 lblk_num, |
151 | struct page *src_page, struct page *dest_page, | 151 | struct page *src_page, struct page *dest_page, |
152 | unsigned int src_len, unsigned int src_offset, | 152 | unsigned int len, unsigned int offs, |
153 | gfp_t gfp_flags) | 153 | gfp_t gfp_flags) |
154 | { | 154 | { |
155 | struct { | 155 | struct { |
@@ -163,6 +163,8 @@ static int do_page_crypto(const struct inode *inode, | |||
163 | struct crypto_skcipher *tfm = ci->ci_ctfm; | 163 | struct crypto_skcipher *tfm = ci->ci_ctfm; |
164 | int res = 0; | 164 | int res = 0; |
165 | 165 | ||
166 | BUG_ON(len == 0); | ||
167 | |||
166 | req = skcipher_request_alloc(tfm, gfp_flags); | 168 | req = skcipher_request_alloc(tfm, gfp_flags); |
167 | if (!req) { | 169 | if (!req) { |
168 | printk_ratelimited(KERN_ERR | 170 | printk_ratelimited(KERN_ERR |
@@ -176,14 +178,14 @@ static int do_page_crypto(const struct inode *inode, | |||
176 | page_crypt_complete, &ecr); | 178 | page_crypt_complete, &ecr); |
177 | 179 | ||
178 | BUILD_BUG_ON(sizeof(xts_tweak) != FS_XTS_TWEAK_SIZE); | 180 | BUILD_BUG_ON(sizeof(xts_tweak) != FS_XTS_TWEAK_SIZE); |
179 | xts_tweak.index = cpu_to_le64(index); | 181 | xts_tweak.index = cpu_to_le64(lblk_num); |
180 | memset(xts_tweak.padding, 0, sizeof(xts_tweak.padding)); | 182 | memset(xts_tweak.padding, 0, sizeof(xts_tweak.padding)); |
181 | 183 | ||
182 | sg_init_table(&dst, 1); | 184 | sg_init_table(&dst, 1); |
183 | sg_set_page(&dst, dest_page, src_len, src_offset); | 185 | sg_set_page(&dst, dest_page, len, offs); |
184 | sg_init_table(&src, 1); | 186 | sg_init_table(&src, 1); |
185 | sg_set_page(&src, src_page, src_len, src_offset); | 187 | sg_set_page(&src, src_page, len, offs); |
186 | skcipher_request_set_crypt(req, &src, &dst, src_len, &xts_tweak); | 188 | skcipher_request_set_crypt(req, &src, &dst, len, &xts_tweak); |
187 | if (rw == FS_DECRYPT) | 189 | if (rw == FS_DECRYPT) |
188 | res = crypto_skcipher_decrypt(req); | 190 | res = crypto_skcipher_decrypt(req); |
189 | else | 191 | else |
@@ -214,44 +216,53 @@ static struct page *alloc_bounce_page(struct fscrypt_ctx *ctx, gfp_t gfp_flags) | |||
214 | 216 | ||
215 | /** | 217 | /** |
216 | * fscypt_encrypt_page() - Encrypts a page | 218 | * fscypt_encrypt_page() - Encrypts a page |
217 | * @inode: The inode for which the encryption should take place | 219 | * @inode: The inode for which the encryption should take place |
218 | * @plaintext_page: The page to encrypt. Must be locked. | 220 | * @page: The page to encrypt. Must be locked for bounce-page |
219 | * @plaintext_len: Length of plaintext within page | 221 | * encryption. |
220 | * @plaintext_offset: Offset of plaintext within page | 222 | * @len: Length of data to encrypt in @page and encrypted |
221 | * @index: Index for encryption. This is mainly the page index, but | 223 | * data in returned page. |
222 | * but might be different for multiple calls on same page. | 224 | * @offs: Offset of data within @page and returned |
223 | * @gfp_flags: The gfp flag for memory allocation | 225 | * page holding encrypted data. |
226 | * @lblk_num: Logical block number. This must be unique for multiple | ||
227 | * calls with same inode, except when overwriting | ||
228 | * previously written data. | ||
229 | * @gfp_flags: The gfp flag for memory allocation | ||
224 | * | 230 | * |
225 | * Encrypts plaintext_page using the ctx encryption context. If | 231 | * Encrypts @page using the ctx encryption context. Performs encryption |
226 | * the filesystem supports it, encryption is performed in-place, otherwise a | 232 | * either in-place or into a newly allocated bounce page. |
227 | * new ciphertext_page is allocated and returned. | 233 | * Called on the page write path. |
228 | * | 234 | * |
229 | * Called on the page write path. The caller must call | 235 | * Bounce page allocation is the default. |
236 | * In this case, the contents of @page are encrypted and stored in an | ||
237 | * allocated bounce page. @page has to be locked and the caller must call | ||
230 | * fscrypt_restore_control_page() on the returned ciphertext page to | 238 | * fscrypt_restore_control_page() on the returned ciphertext page to |
231 | * release the bounce buffer and the encryption context. | 239 | * release the bounce buffer and the encryption context. |
232 | * | 240 | * |
233 | * Return: An allocated page with the encrypted content on success. Else, an | 241 | * In-place encryption is used by setting the FS_CFLG_INPLACE_ENCRYPTION flag in |
242 | * fscrypt_operations. Here, the input-page is returned with its content | ||
243 | * encrypted. | ||
244 | * | ||
245 | * Return: A page with the encrypted content on success. Else, an | ||
234 | * error value or NULL. | 246 | * error value or NULL. |
235 | */ | 247 | */ |
236 | struct page *fscrypt_encrypt_page(const struct inode *inode, | 248 | struct page *fscrypt_encrypt_page(const struct inode *inode, |
237 | struct page *plaintext_page, | 249 | struct page *page, |
238 | unsigned int plaintext_len, | 250 | unsigned int len, |
239 | unsigned int plaintext_offset, | 251 | unsigned int offs, |
240 | pgoff_t index, gfp_t gfp_flags) | 252 | u64 lblk_num, gfp_t gfp_flags) |
241 | 253 | ||
242 | { | 254 | { |
243 | struct fscrypt_ctx *ctx; | 255 | struct fscrypt_ctx *ctx; |
244 | struct page *ciphertext_page = plaintext_page; | 256 | struct page *ciphertext_page = page; |
245 | int err; | 257 | int err; |
246 | 258 | ||
247 | BUG_ON(plaintext_len % FS_CRYPTO_BLOCK_SIZE != 0); | 259 | BUG_ON(len % FS_CRYPTO_BLOCK_SIZE != 0); |
248 | 260 | ||
249 | if (inode->i_sb->s_cop->flags & FS_CFLG_INPLACE_ENCRYPTION) { | 261 | if (inode->i_sb->s_cop->flags & FS_CFLG_INPLACE_ENCRYPTION) { |
250 | /* with inplace-encryption we just encrypt the page */ | 262 | /* with inplace-encryption we just encrypt the page */ |
251 | err = do_page_crypto(inode, FS_ENCRYPT, index, | 263 | err = do_page_crypto(inode, FS_ENCRYPT, lblk_num, |
252 | plaintext_page, ciphertext_page, | 264 | page, ciphertext_page, |
253 | plaintext_len, plaintext_offset, | 265 | len, offs, gfp_flags); |
254 | gfp_flags); | ||
255 | if (err) | 266 | if (err) |
256 | return ERR_PTR(err); | 267 | return ERR_PTR(err); |
257 | 268 | ||
@@ -267,11 +278,10 @@ struct page *fscrypt_encrypt_page(const struct inode *inode, | |||
267 | if (IS_ERR(ciphertext_page)) | 278 | if (IS_ERR(ciphertext_page)) |
268 | goto errout; | 279 | goto errout; |
269 | 280 | ||
270 | ctx->w.control_page = plaintext_page; | 281 | ctx->w.control_page = page; |
271 | err = do_page_crypto(inode, FS_ENCRYPT, index, | 282 | err = do_page_crypto(inode, FS_ENCRYPT, lblk_num, |
272 | plaintext_page, ciphertext_page, | 283 | page, ciphertext_page, |
273 | plaintext_len, plaintext_offset, | 284 | len, offs, gfp_flags); |
274 | gfp_flags); | ||
275 | if (err) { | 285 | if (err) { |
276 | ciphertext_page = ERR_PTR(err); | 286 | ciphertext_page = ERR_PTR(err); |
277 | goto errout; | 287 | goto errout; |
@@ -289,11 +299,12 @@ EXPORT_SYMBOL(fscrypt_encrypt_page); | |||
289 | 299 | ||
290 | /** | 300 | /** |
291 | * fscrypt_decrypt_page() - Decrypts a page in-place | 301 | * fscrypt_decrypt_page() - Decrypts a page in-place |
292 | * @inode: Encrypted inode to decrypt. | 302 | * @inode: The corresponding inode for the page to decrypt. |
293 | * @page: The page to decrypt. Must be locked. | 303 | * @page: The page to decrypt. Must be locked in case |
294 | * @len: Number of bytes in @page to be decrypted. | 304 | * it is a writeback page. |
295 | * @offs: Start of data in @page. | 305 | * @len: Number of bytes in @page to be decrypted. |
296 | * @index: Index for encryption. | 306 | * @offs: Start of data in @page. |
307 | * @lblk_num: Logical block number. | ||
297 | * | 308 | * |
298 | * Decrypts page in-place using the ctx encryption context. | 309 | * Decrypts page in-place using the ctx encryption context. |
299 | * | 310 | * |
@@ -302,10 +313,10 @@ EXPORT_SYMBOL(fscrypt_encrypt_page); | |||
302 | * Return: Zero on success, non-zero otherwise. | 313 | * Return: Zero on success, non-zero otherwise. |
303 | */ | 314 | */ |
304 | int fscrypt_decrypt_page(const struct inode *inode, struct page *page, | 315 | int fscrypt_decrypt_page(const struct inode *inode, struct page *page, |
305 | unsigned int len, unsigned int offs, pgoff_t index) | 316 | unsigned int len, unsigned int offs, u64 lblk_num) |
306 | { | 317 | { |
307 | return do_page_crypto(inode, FS_DECRYPT, index, page, page, len, offs, | 318 | return do_page_crypto(inode, FS_DECRYPT, lblk_num, page, page, len, |
308 | GFP_NOFS); | 319 | offs, GFP_NOFS); |
309 | } | 320 | } |
310 | EXPORT_SYMBOL(fscrypt_decrypt_page); | 321 | EXPORT_SYMBOL(fscrypt_decrypt_page); |
311 | 322 | ||