crypto.c (14e034a61c908d4479be1a7ee9fe5b8d3d1f09b8) crypto.c (77cdb7e17e39ebb986f60bbd3c2b3507687bf475)
1// SPDX-License-Identifier: GPL-2.0
2/*
3 * The base64 encode/decode code was copied from fscrypt:
4 * Copyright (C) 2015, Google, Inc.
5 * Copyright (C) 2015, Motorola Mobility
6 * Written by Uday Savagaonkar, 2014.
7 * Modified by Jaegeuk Kim, 2015.
8 */
9#include <linux/ceph/ceph_debug.h>
10#include <linux/xattr.h>
11#include <linux/fscrypt.h>
1// SPDX-License-Identifier: GPL-2.0
2/*
3 * The base64 encode/decode code was copied from fscrypt:
4 * Copyright (C) 2015, Google, Inc.
5 * Copyright (C) 2015, Motorola Mobility
6 * Written by Uday Savagaonkar, 2014.
7 * Modified by Jaegeuk Kim, 2015.
8 */
9#include <linux/ceph/ceph_debug.h>
10#include <linux/xattr.h>
11#include <linux/fscrypt.h>
12#include <linux/ceph/striper.h>
12
13#include "super.h"
14#include "mds_client.h"
15#include "crypto.h"
16
17/*
18 * The base64url encoding used by fscrypt includes the '_' character, which may
19 * cause problems in snapshot names (which can not start with '_'). Thus, we

--- 340 unchanged lines hidden (view full) ---

360 return err;
361 if (!had_key && fscrypt_has_encryption_key(dir)) {
362 /* directory just got unlocked, mark it as not complete */
363 ceph_dir_clear_complete(dir);
364 return 1;
365 }
366 return 0;
367}
13
14#include "super.h"
15#include "mds_client.h"
16#include "crypto.h"
17
18/*
19 * The base64url encoding used by fscrypt includes the '_' character, which may
20 * cause problems in snapshot names (which can not start with '_'). Thus, we

--- 340 unchanged lines hidden (view full) ---

361 return err;
362 if (!had_key && fscrypt_has_encryption_key(dir)) {
363 /* directory just got unlocked, mark it as not complete */
364 ceph_dir_clear_complete(dir);
365 return 1;
366 }
367 return 0;
368}
369
370int ceph_fscrypt_decrypt_block_inplace(const struct inode *inode,
371 struct page *page, unsigned int len,
372 unsigned int offs, u64 lblk_num)
373{
374 dout("%s: len %u offs %u blk %llu\n", __func__, len, offs, lblk_num);
375 return fscrypt_decrypt_block_inplace(inode, page, len, offs, lblk_num);
376}
377
378int ceph_fscrypt_encrypt_block_inplace(const struct inode *inode,
379 struct page *page, unsigned int len,
380 unsigned int offs, u64 lblk_num,
381 gfp_t gfp_flags)
382{
383 dout("%s: len %u offs %u blk %llu\n", __func__, len, offs, lblk_num);
384 return fscrypt_encrypt_block_inplace(inode, page, len, offs, lblk_num,
385 gfp_flags);
386}
387
388/**
389 * ceph_fscrypt_decrypt_pages - decrypt an array of pages
390 * @inode: pointer to inode associated with these pages
391 * @page: pointer to page array
392 * @off: offset into the file that the read data starts
393 * @len: max length to decrypt
394 *
395 * Decrypt an array of fscrypt'ed pages and return the amount of
396 * data decrypted. Any data in the page prior to the start of the
397 * first complete block in the read is ignored. Any incomplete
398 * crypto blocks at the end of the array are ignored (and should
399 * probably be zeroed by the caller).
400 *
401 * Returns the length of the decrypted data or a negative errno.
402 */
403int ceph_fscrypt_decrypt_pages(struct inode *inode, struct page **page,
404 u64 off, int len)
405{
406 int i, num_blocks;
407 u64 baseblk = off >> CEPH_FSCRYPT_BLOCK_SHIFT;
408 int ret = 0;
409
410 /*
411 * We can't deal with partial blocks on an encrypted file, so mask off
412 * the last bit.
413 */
414 num_blocks = ceph_fscrypt_blocks(off, len & CEPH_FSCRYPT_BLOCK_MASK);
415
416 /* Decrypt each block */
417 for (i = 0; i < num_blocks; ++i) {
418 int blkoff = i << CEPH_FSCRYPT_BLOCK_SHIFT;
419 int pgidx = blkoff >> PAGE_SHIFT;
420 unsigned int pgoffs = offset_in_page(blkoff);
421 int fret;
422
423 fret = ceph_fscrypt_decrypt_block_inplace(inode, page[pgidx],
424 CEPH_FSCRYPT_BLOCK_SIZE, pgoffs,
425 baseblk + i);
426 if (fret < 0) {
427 if (ret == 0)
428 ret = fret;
429 break;
430 }
431 ret += CEPH_FSCRYPT_BLOCK_SIZE;
432 }
433 return ret;
434}
435
436/**
437 * ceph_fscrypt_decrypt_extents: decrypt received extents in given buffer
438 * @inode: inode associated with pages being decrypted
439 * @page: pointer to page array
440 * @off: offset into the file that the data in page[0] starts
441 * @map: pointer to extent array
442 * @ext_cnt: length of extent array
443 *
444 * Given an extent map and a page array, decrypt the received data in-place,
445 * skipping holes. Returns the offset into buffer of end of last decrypted
446 * block.
447 */
448int ceph_fscrypt_decrypt_extents(struct inode *inode, struct page **page,
449 u64 off, struct ceph_sparse_extent *map,
450 u32 ext_cnt)
451{
452 int i, ret = 0;
453 struct ceph_inode_info *ci = ceph_inode(inode);
454 u64 objno, objoff;
455 u32 xlen;
456
457 /* Nothing to do for empty array */
458 if (ext_cnt == 0) {
459 dout("%s: empty array, ret 0\n", __func__);
460 return 0;
461 }
462
463 ceph_calc_file_object_mapping(&ci->i_layout, off, map[0].len,
464 &objno, &objoff, &xlen);
465
466 for (i = 0; i < ext_cnt; ++i) {
467 struct ceph_sparse_extent *ext = &map[i];
468 int pgsoff = ext->off - objoff;
469 int pgidx = pgsoff >> PAGE_SHIFT;
470 int fret;
471
472 if ((ext->off | ext->len) & ~CEPH_FSCRYPT_BLOCK_MASK) {
473 pr_warn("%s: bad encrypted sparse extent idx %d off %llx len %llx\n",
474 __func__, i, ext->off, ext->len);
475 return -EIO;
476 }
477 fret = ceph_fscrypt_decrypt_pages(inode, &page[pgidx],
478 off + pgsoff, ext->len);
479 dout("%s: [%d] 0x%llx~0x%llx fret %d\n", __func__, i,
480 ext->off, ext->len, fret);
481 if (fret < 0) {
482 if (ret == 0)
483 ret = fret;
484 break;
485 }
486 ret = pgsoff + fret;
487 }
488 dout("%s: ret %d\n", __func__, ret);
489 return ret;
490}
491
492/**
493 * ceph_fscrypt_encrypt_pages - encrypt an array of pages
494 * @inode: pointer to inode associated with these pages
495 * @page: pointer to page array
496 * @off: offset into the file that the data starts
497 * @len: max length to encrypt
498 * @gfp: gfp flags to use for allocation
499 *
500 * Decrypt an array of cleartext pages and return the amount of
501 * data encrypted. Any data in the page prior to the start of the
502 * first complete block in the read is ignored. Any incomplete
503 * crypto blocks at the end of the array are ignored.
504 *
505 * Returns the length of the encrypted data or a negative errno.
506 */
507int ceph_fscrypt_encrypt_pages(struct inode *inode, struct page **page, u64 off,
508 int len, gfp_t gfp)
509{
510 int i, num_blocks;
511 u64 baseblk = off >> CEPH_FSCRYPT_BLOCK_SHIFT;
512 int ret = 0;
513
514 /*
515 * We can't deal with partial blocks on an encrypted file, so mask off
516 * the last bit.
517 */
518 num_blocks = ceph_fscrypt_blocks(off, len & CEPH_FSCRYPT_BLOCK_MASK);
519
520 /* Encrypt each block */
521 for (i = 0; i < num_blocks; ++i) {
522 int blkoff = i << CEPH_FSCRYPT_BLOCK_SHIFT;
523 int pgidx = blkoff >> PAGE_SHIFT;
524 unsigned int pgoffs = offset_in_page(blkoff);
525 int fret;
526
527 fret = ceph_fscrypt_encrypt_block_inplace(inode, page[pgidx],
528 CEPH_FSCRYPT_BLOCK_SIZE, pgoffs,
529 baseblk + i, gfp);
530 if (fret < 0) {
531 if (ret == 0)
532 ret = fret;
533 break;
534 }
535 ret += CEPH_FSCRYPT_BLOCK_SIZE;
536 }
537 return ret;
538}