158ae7468SRichard Weinberger /* 258ae7468SRichard Weinberger * This contains encryption functions for per-file encryption. 358ae7468SRichard Weinberger * 458ae7468SRichard Weinberger * Copyright (C) 2015, Google, Inc. 558ae7468SRichard Weinberger * Copyright (C) 2015, Motorola Mobility 658ae7468SRichard Weinberger * 758ae7468SRichard Weinberger * Written by Michael Halcrow, 2014. 858ae7468SRichard Weinberger * 958ae7468SRichard Weinberger * Filename encryption additions 1058ae7468SRichard Weinberger * Uday Savagaonkar, 2014 1158ae7468SRichard Weinberger * Encryption policy handling additions 1258ae7468SRichard Weinberger * Ildar Muslukhov, 2014 1358ae7468SRichard Weinberger * Add fscrypt_pullback_bio_page() 1458ae7468SRichard Weinberger * Jaegeuk Kim, 2015. 1558ae7468SRichard Weinberger * 1658ae7468SRichard Weinberger * This has not yet undergone a rigorous security audit. 1758ae7468SRichard Weinberger * 1858ae7468SRichard Weinberger * The usage of AES-XTS should conform to recommendations in NIST 1958ae7468SRichard Weinberger * Special Publication 800-38E and IEEE P1619/D16. 2058ae7468SRichard Weinberger */ 2158ae7468SRichard Weinberger 2258ae7468SRichard Weinberger #include <linux/pagemap.h> 2358ae7468SRichard Weinberger #include <linux/module.h> 2458ae7468SRichard Weinberger #include <linux/bio.h> 2558ae7468SRichard Weinberger #include <linux/namei.h> 2658ae7468SRichard Weinberger #include "fscrypt_private.h" 2758ae7468SRichard Weinberger 2858ae7468SRichard Weinberger /* 2958ae7468SRichard Weinberger * Call fscrypt_decrypt_page on every single page, reusing the encryption 3058ae7468SRichard Weinberger * context. 3158ae7468SRichard Weinberger */ 3258ae7468SRichard Weinberger static void completion_pages(struct work_struct *work) 3358ae7468SRichard Weinberger { 3458ae7468SRichard Weinberger struct fscrypt_ctx *ctx = 3558ae7468SRichard Weinberger container_of(work, struct fscrypt_ctx, r.work); 3658ae7468SRichard Weinberger struct bio *bio = ctx->r.bio; 3758ae7468SRichard Weinberger struct bio_vec *bv; 3858ae7468SRichard Weinberger int i; 3958ae7468SRichard Weinberger 4058ae7468SRichard Weinberger bio_for_each_segment_all(bv, bio, i) { 4158ae7468SRichard Weinberger struct page *page = bv->bv_page; 4258ae7468SRichard Weinberger int ret = fscrypt_decrypt_page(page->mapping->host, page, 4358ae7468SRichard Weinberger PAGE_SIZE, 0, page->index); 4458ae7468SRichard Weinberger 4558ae7468SRichard Weinberger if (ret) { 4658ae7468SRichard Weinberger WARN_ON_ONCE(1); 4758ae7468SRichard Weinberger SetPageError(page); 4858ae7468SRichard Weinberger } else { 4958ae7468SRichard Weinberger SetPageUptodate(page); 5058ae7468SRichard Weinberger } 5158ae7468SRichard Weinberger unlock_page(page); 5258ae7468SRichard Weinberger } 5358ae7468SRichard Weinberger fscrypt_release_ctx(ctx); 5458ae7468SRichard Weinberger bio_put(bio); 5558ae7468SRichard Weinberger } 5658ae7468SRichard Weinberger 5758ae7468SRichard Weinberger void fscrypt_decrypt_bio_pages(struct fscrypt_ctx *ctx, struct bio *bio) 5858ae7468SRichard Weinberger { 5958ae7468SRichard Weinberger INIT_WORK(&ctx->r.work, completion_pages); 6058ae7468SRichard Weinberger ctx->r.bio = bio; 6158ae7468SRichard Weinberger queue_work(fscrypt_read_workqueue, &ctx->r.work); 6258ae7468SRichard Weinberger } 6358ae7468SRichard Weinberger EXPORT_SYMBOL(fscrypt_decrypt_bio_pages); 6458ae7468SRichard Weinberger 6558ae7468SRichard Weinberger void fscrypt_pullback_bio_page(struct page **page, bool restore) 6658ae7468SRichard Weinberger { 6758ae7468SRichard Weinberger struct fscrypt_ctx *ctx; 6858ae7468SRichard Weinberger struct page *bounce_page; 6958ae7468SRichard Weinberger 7058ae7468SRichard Weinberger /* The bounce data pages are unmapped. */ 7158ae7468SRichard Weinberger if ((*page)->mapping) 7258ae7468SRichard Weinberger return; 7358ae7468SRichard Weinberger 7458ae7468SRichard Weinberger /* The bounce data page is unmapped. */ 7558ae7468SRichard Weinberger bounce_page = *page; 7658ae7468SRichard Weinberger ctx = (struct fscrypt_ctx *)page_private(bounce_page); 7758ae7468SRichard Weinberger 7858ae7468SRichard Weinberger /* restore control page */ 7958ae7468SRichard Weinberger *page = ctx->w.control_page; 8058ae7468SRichard Weinberger 8158ae7468SRichard Weinberger if (restore) 8258ae7468SRichard Weinberger fscrypt_restore_control_page(bounce_page); 8358ae7468SRichard Weinberger } 8458ae7468SRichard Weinberger EXPORT_SYMBOL(fscrypt_pullback_bio_page); 8558ae7468SRichard Weinberger 8658ae7468SRichard Weinberger int fscrypt_zeroout_range(const struct inode *inode, pgoff_t lblk, 8758ae7468SRichard Weinberger sector_t pblk, unsigned int len) 8858ae7468SRichard Weinberger { 8958ae7468SRichard Weinberger struct fscrypt_ctx *ctx; 9058ae7468SRichard Weinberger struct page *ciphertext_page = NULL; 9158ae7468SRichard Weinberger struct bio *bio; 9258ae7468SRichard Weinberger int ret, err = 0; 9358ae7468SRichard Weinberger 9458ae7468SRichard Weinberger BUG_ON(inode->i_sb->s_blocksize != PAGE_SIZE); 9558ae7468SRichard Weinberger 9658ae7468SRichard Weinberger ctx = fscrypt_get_ctx(inode, GFP_NOFS); 9758ae7468SRichard Weinberger if (IS_ERR(ctx)) 9858ae7468SRichard Weinberger return PTR_ERR(ctx); 9958ae7468SRichard Weinberger 10058ae7468SRichard Weinberger ciphertext_page = fscrypt_alloc_bounce_page(ctx, GFP_NOWAIT); 10158ae7468SRichard Weinberger if (IS_ERR(ciphertext_page)) { 10258ae7468SRichard Weinberger err = PTR_ERR(ciphertext_page); 10358ae7468SRichard Weinberger goto errout; 10458ae7468SRichard Weinberger } 10558ae7468SRichard Weinberger 10658ae7468SRichard Weinberger while (len--) { 10758ae7468SRichard Weinberger err = fscrypt_do_page_crypto(inode, FS_ENCRYPT, lblk, 10858ae7468SRichard Weinberger ZERO_PAGE(0), ciphertext_page, 10958ae7468SRichard Weinberger PAGE_SIZE, 0, GFP_NOFS); 11058ae7468SRichard Weinberger if (err) 11158ae7468SRichard Weinberger goto errout; 11258ae7468SRichard Weinberger 11358ae7468SRichard Weinberger bio = bio_alloc(GFP_NOWAIT, 1); 11458ae7468SRichard Weinberger if (!bio) { 11558ae7468SRichard Weinberger err = -ENOMEM; 11658ae7468SRichard Weinberger goto errout; 11758ae7468SRichard Weinberger } 11858ae7468SRichard Weinberger bio->bi_bdev = inode->i_sb->s_bdev; 11958ae7468SRichard Weinberger bio->bi_iter.bi_sector = 12058ae7468SRichard Weinberger pblk << (inode->i_sb->s_blocksize_bits - 9); 12158ae7468SRichard Weinberger bio_set_op_attrs(bio, REQ_OP_WRITE, 0); 12258ae7468SRichard Weinberger ret = bio_add_page(bio, ciphertext_page, 12358ae7468SRichard Weinberger inode->i_sb->s_blocksize, 0); 12458ae7468SRichard Weinberger if (ret != inode->i_sb->s_blocksize) { 12558ae7468SRichard Weinberger /* should never happen! */ 12658ae7468SRichard Weinberger WARN_ON(1); 12758ae7468SRichard Weinberger bio_put(bio); 12858ae7468SRichard Weinberger err = -EIO; 12958ae7468SRichard Weinberger goto errout; 13058ae7468SRichard Weinberger } 13158ae7468SRichard Weinberger err = submit_bio_wait(bio); 1324e4cbee9SChristoph Hellwig if (err == 0 && bio->bi_status) 13358ae7468SRichard Weinberger err = -EIO; 13458ae7468SRichard Weinberger bio_put(bio); 13558ae7468SRichard Weinberger if (err) 13658ae7468SRichard Weinberger goto errout; 13758ae7468SRichard Weinberger lblk++; 13858ae7468SRichard Weinberger pblk++; 13958ae7468SRichard Weinberger } 14058ae7468SRichard Weinberger err = 0; 14158ae7468SRichard Weinberger errout: 14258ae7468SRichard Weinberger fscrypt_release_ctx(ctx); 14358ae7468SRichard Weinberger return err; 14458ae7468SRichard Weinberger } 14558ae7468SRichard Weinberger EXPORT_SYMBOL(fscrypt_zeroout_range); 146