From patchwork Fri Oct 21 12:48:16 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Weinberger X-Patchwork-Id: 685089 X-Patchwork-Delegate: richard@nod.at Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from bombadil.infradead.org (bombadil.infradead.org [IPv6:2001:1868:205::9]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3t0ltq1y3vz9t1P for ; Fri, 21 Oct 2016 23:52:03 +1100 (AEDT) Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.85_2 #1 (Red Hat Linux)) id 1bxZGo-0004jM-FP; Fri, 21 Oct 2016 12:49:58 +0000 Received: from mail.sigma-star.at ([95.130.255.111]) by bombadil.infradead.org with esmtp (Exim 4.85_2 #1 (Red Hat Linux)) id 1bxZGO-0004HV-1z for linux-mtd@lists.infradead.org; Fri, 21 Oct 2016 12:49:36 +0000 Received: from localhost (localhost.localdomain [127.0.0.1]) by mail.sigma-star.at (Postfix) with ESMTP id 720DE24E0005; Fri, 21 Oct 2016 14:49:08 +0200 (CEST) X-Virus-Scanned: amavisd-new at mail.sigma-star.at Received: from linux.site (richard.vpn.sigmapriv.at [10.3.0.5]) by mail.sigma-star.at (Postfix) with ESMTPSA id 6328224E0003; Fri, 21 Oct 2016 14:49:07 +0200 (CEST) From: Richard Weinberger To: linux-mtd@lists.infradead.org Subject: [PATCH 01/26] fscrypto: Add buffer operations Date: Fri, 21 Oct 2016 14:48:16 +0200 Message-Id: <1477054121-10198-2-git-send-email-richard@nod.at> X-Mailer: git-send-email 2.7.3 In-Reply-To: <1477054121-10198-1-git-send-email-richard@nod.at> References: <1477054121-10198-1-git-send-email-richard@nod.at> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20161021_054932_568039_7269F1D4 X-CRM114-Status: GOOD ( 15.10 ) X-Spam-Score: -1.9 (-) X-Spam-Report: SpamAssassin version 3.4.0 on bombadil.infradead.org summary: Content analysis details: (-1.9 points) pts rule name description ---- ---------------------- -------------------------------------------------- -0.0 SPF_PASS SPF: sender matches SPF record -1.9 BAYES_00 BODY: Bayes spam probability is 0 to 1% [score: 0.0000] X-BeenThere: linux-mtd@lists.infradead.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: Linux MTD discussion mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: david@sigma-star.at, tytso@mit.edu, dedekind1@gmail.com, Richard Weinberger , adrian.hunter@intel.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, jaegeuk@kernel.org, dengler@linutronix.de, sbabic@denx.de MIME-Version: 1.0 Sender: "linux-mtd" Errors-To: linux-mtd-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org Not all filesystems operate on pages, therefore offer operations to en/decrypt buffers. Of course these buffers have to be allocated in a way such that the kernel crypto framework can work with them. Signed-off-by: Richard Weinberger --- fs/crypto/crypto.c | 63 +++++++++++++++++++++++++++++++++++++++--------- include/linux/fscrypto.h | 24 ++++++++++++++++++ 2 files changed, 76 insertions(+), 11 deletions(-) diff --git a/fs/crypto/crypto.c b/fs/crypto/crypto.c index c502c116924c..1c2f9516b4be 100644 --- a/fs/crypto/crypto.c +++ b/fs/crypto/crypto.c @@ -147,15 +147,14 @@ typedef enum { FS_ENCRYPT, } fscrypt_direction_t; -static int do_page_crypto(struct inode *inode, - fscrypt_direction_t rw, pgoff_t index, - struct page *src_page, struct page *dest_page, - gfp_t gfp_flags) +static int do_crypto(struct inode *inode, + fscrypt_direction_t rw, pgoff_t index, + struct scatterlist *src, struct scatterlist *dst, + unsigned int cryptlen, gfp_t gfp_flags) { u8 xts_tweak[FS_XTS_TWEAK_SIZE]; struct skcipher_request *req = NULL; DECLARE_FS_COMPLETION_RESULT(ecr); - struct scatterlist dst, src; struct fscrypt_info *ci = inode->i_crypt_info; struct crypto_skcipher *tfm = ci->ci_ctfm; int res = 0; @@ -177,12 +176,8 @@ static int do_page_crypto(struct inode *inode, memset(&xts_tweak[sizeof(index)], 0, FS_XTS_TWEAK_SIZE - sizeof(index)); - sg_init_table(&dst, 1); - sg_set_page(&dst, dest_page, PAGE_SIZE, 0); - sg_init_table(&src, 1); - sg_set_page(&src, src_page, PAGE_SIZE, 0); - skcipher_request_set_crypt(req, &src, &dst, PAGE_SIZE, - xts_tweak); + skcipher_request_set_crypt(req, src, dst, cryptlen, + xts_tweak); if (rw == FS_DECRYPT) res = crypto_skcipher_decrypt(req); else @@ -202,6 +197,34 @@ static int do_page_crypto(struct inode *inode, return 0; } +static int do_page_crypto(struct inode *inode, + fscrypt_direction_t rw, pgoff_t index, + struct page *src_page, struct page *dst_page, + gfp_t gfp_flags) +{ + struct scatterlist src, dst; + + sg_init_table(&src, 1); + sg_set_page(&src, src_page, PAGE_SIZE, 0); + sg_init_table(&dst, 1); + sg_set_page(&dst, dst_page, PAGE_SIZE, 0); + + return do_crypto(inode, rw, index, &src, &dst, PAGE_SIZE, gfp_flags); +} + +static int do_buf_crypto(struct inode *inode, + fscrypt_direction_t rw, pgoff_t index, + const void *src_buf, const void *dst_buf, + unsigned int buflen, gfp_t gfp_flags) +{ + struct scatterlist src, dst; + + sg_init_one(&src, src_buf, buflen); + sg_init_one(&dst, dst_buf, buflen); + + return do_crypto(inode, rw, index, &src, &dst, buflen, gfp_flags); +} + static struct page *alloc_bounce_page(struct fscrypt_ctx *ctx, gfp_t gfp_flags) { ctx->w.bounce_page = mempool_alloc(fscrypt_bounce_page_pool, gfp_flags); @@ -264,6 +287,24 @@ errout: } EXPORT_SYMBOL(fscrypt_encrypt_page); +int fscrypt_encrypt_buffer(struct inode *inode, const void *plaintext_buf, + const void *ciphertext_buf, unsigned int buflen, + pgoff_t index, gfp_t gfp_flags) +{ + return do_buf_crypto(inode, FS_ENCRYPT, index, plaintext_buf, + ciphertext_buf, buflen, gfp_flags); +} +EXPORT_SYMBOL(fscrypt_encrypt_buffer); + +int fscrypt_decrypt_buffer(struct inode *inode, const void *ciphertext_buf, + const void *plaintext_buf, unsigned int buflen, + pgoff_t index, gfp_t gfp_flags) +{ + return do_buf_crypto(inode, FS_DECRYPT, index, ciphertext_buf, + plaintext_buf, buflen, gfp_flags); +} +EXPORT_SYMBOL(fscrypt_decrypt_buffer); + /** * f2crypt_decrypt_page() - Decrypts a page in-place * @page: The page to decrypt. Must be locked. diff --git a/include/linux/fscrypto.h b/include/linux/fscrypto.h index 76cff18bb032..a9628b4882e7 100644 --- a/include/linux/fscrypto.h +++ b/include/linux/fscrypto.h @@ -273,6 +273,12 @@ extern void fscrypt_pullback_bio_page(struct page **, bool); extern void fscrypt_restore_control_page(struct page *); extern int fscrypt_zeroout_range(struct inode *, pgoff_t, sector_t, unsigned int); +int fscrypt_encrypt_buffer(struct inode *inode, const void *plaintext_buf, + const void *ciphertext_buf, unsigned int buflen, + pgoff_t index, gfp_t gfp_flags); +int fscrypt_decrypt_buffer(struct inode *inode, const void *ciphertext_buf, + const void *plaintext_buf, unsigned int buflen, + pgoff_t index, gfp_t gfp_flags); /* policy.c */ extern int fscrypt_process_policy(struct file *, const struct fscrypt_policy *); extern int fscrypt_get_policy(struct inode *, struct fscrypt_policy *); @@ -418,6 +424,24 @@ static inline void fscrypt_notsupp_fname_free_buffer(struct fscrypt_str *c) return; } +static inline int fscrypt_notsupp_encrypt_buffer(const struct inode *inode, + const void *plaintext_buf, + const void *ciphertext_buf, + unsigned int buflen, + pgoff_t index, gfp_t gfp_flags) +{ + return -EOPNOTSUPP; +} + +static inline int fscrypt_notsupp_decrypt_buffer(const struct inode *inode, + const void *ciphertext_buf, + const void *plaintext_buf, + unsigned int buflen, + pgoff_t index, gfp_t gfp_flags) +{ + return -EOPNOTSUPP; +} + static inline int fscrypt_notsupp_fname_disk_to_usr(struct inode *inode, u32 hash, u32 minor_hash, const struct fscrypt_str *iname,