linux-crypto.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Herbert Xu <herbert@gondor.apana.org.au>
To: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Cc: "open list:HARDWARE RANDOM NUMBER GENERATOR CORE" 
	<linux-crypto@vger.kernel.org>,
	Eric Biggers <ebiggers@kernel.org>
Subject: crypto: blkcipher - Unmap pages after an external error
Date: Tue, 3 Sep 2019 17:09:19 +1000	[thread overview]
Message-ID: <20190903070919.GA10892@gondor.apana.org.au> (raw)
In-Reply-To: <20190903070501.GA9978@gondor.apana.org.au>

blkcipher_walk_done may be called with an error by internal or
external callers.  For those internal callers we shouldn't unmap
pages but for external callers we must unmap any pages that are
in use.

This patch adds a new function blkcipher_walk_unwind so that we
can eliminate the internal callers.

Reported-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Fixes: 0868def3e410 ("crypto: blkcipher - fix crash flushing...")
Cc: <stable@vger.kernel.org>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>

diff --git a/crypto/blkcipher.c b/crypto/blkcipher.c
index 48a33817de11..eafed44cafdd 100644
--- a/crypto/blkcipher.c
+++ b/crypto/blkcipher.c
@@ -31,6 +31,8 @@ enum {
 	BLKCIPHER_WALK_DIFF = 1 << 3,
 };
 
+static int blkcipher_walk_unwind(struct blkcipher_desc *desc,
+				 struct blkcipher_walk *walk, int err);
 static int blkcipher_walk_next(struct blkcipher_desc *desc,
 			       struct blkcipher_walk *walk);
 static int blkcipher_walk_first(struct blkcipher_desc *desc,
@@ -65,18 +67,19 @@ static inline u8 *blkcipher_get_spot(u8 *start, unsigned int len)
 	return max(start, end_page);
 }
 
-static inline void blkcipher_done_slow(struct blkcipher_walk *walk,
-				       unsigned int bsize)
+static inline unsigned int blkcipher_done_slow(struct blkcipher_walk *walk,
+					       unsigned int bsize)
 {
 	u8 *addr;
 
 	addr = (u8 *)ALIGN((unsigned long)walk->buffer, walk->alignmask + 1);
 	addr = blkcipher_get_spot(addr, bsize);
 	scatterwalk_copychunks(addr, &walk->out, bsize, 1);
+	return bsize;
 }
 
-static inline void blkcipher_done_fast(struct blkcipher_walk *walk,
-				       unsigned int n)
+static inline unsigned int blkcipher_done_fast(struct blkcipher_walk *walk,
+					       unsigned int n)
 {
 	if (walk->flags & BLKCIPHER_WALK_COPY) {
 		blkcipher_map_dst(walk);
@@ -90,51 +93,60 @@ static inline void blkcipher_done_fast(struct blkcipher_walk *walk,
 
 	scatterwalk_advance(&walk->in, n);
 	scatterwalk_advance(&walk->out, n);
+
+	return n;
 }
 
 int blkcipher_walk_done(struct blkcipher_desc *desc,
 			struct blkcipher_walk *walk, int err)
 {
-	unsigned int n; /* bytes processed */
-	bool more;
-
-	if (unlikely(err < 0))
-		goto finish;
+	unsigned int nbytes = 0;
 
-	n = walk->nbytes - err;
-	walk->total -= n;
-	more = (walk->total != 0);
+	if (likely(err >= 0)) {
+		unsigned int n = walk->nbytes - err;
 
-	if (likely(!(walk->flags & BLKCIPHER_WALK_SLOW))) {
-		blkcipher_done_fast(walk, n);
-	} else {
-		if (WARN_ON(err)) {
-			/* unexpected case; didn't process all bytes */
+		if (likely(!(walk->flags & BLKCIPHER_WALK_SLOW)))
+			n = blkcipher_done_fast(walk, n);
+		else if (WARN_ON(err)) {
 			err = -EINVAL;
-			goto finish;
-		}
-		blkcipher_done_slow(walk, n);
+			goto err;
+		} else
+			n = blkcipher_done_slow(walk, n);
+
+		nbytes = walk->total - n;
+		err = 0;
 	}
 
-	scatterwalk_done(&walk->in, 0, more);
-	scatterwalk_done(&walk->out, 1, more);
+	scatterwalk_done(&walk->in, 0, nbytes);
+	scatterwalk_done(&walk->out, 1, nbytes);
 
-	if (more) {
+err:
+	walk->total = nbytes;
+	walk->nbytes = nbytes;
+
+	if (nbytes) {
 		crypto_yield(desc->flags);
 		return blkcipher_walk_next(desc, walk);
 	}
-	err = 0;
-finish:
+
+	return blkcipher_walk_unwind(desc, walk, err);
+}
+EXPORT_SYMBOL_GPL(blkcipher_walk_done);
+
+static int blkcipher_walk_unwind(struct blkcipher_desc *desc,
+				 struct blkcipher_walk *walk, int err)
+{
 	walk->nbytes = 0;
+
 	if (walk->iv != desc->info)
 		memcpy(desc->info, walk->iv, walk->ivsize);
 	if (walk->buffer != walk->page)
 		kfree(walk->buffer);
 	if (walk->page)
 		free_page((unsigned long)walk->page);
+
 	return err;
 }
-EXPORT_SYMBOL_GPL(blkcipher_walk_done);
 
 static inline int blkcipher_next_slow(struct blkcipher_desc *desc,
 				      struct blkcipher_walk *walk,
@@ -155,7 +167,7 @@ static inline int blkcipher_next_slow(struct blkcipher_desc *desc,
 	    (alignmask & ~(crypto_tfm_ctx_alignment() - 1));
 	walk->buffer = kmalloc(n, GFP_ATOMIC);
 	if (!walk->buffer)
-		return blkcipher_walk_done(desc, walk, -ENOMEM);
+		return blkcipher_walk_unwind(desc, walk, -ENOMEM);
 
 ok:
 	walk->dst.virt.addr = (u8 *)ALIGN((unsigned long)walk->buffer,
@@ -223,7 +235,7 @@ static int blkcipher_walk_next(struct blkcipher_desc *desc,
 	n = walk->total;
 	if (unlikely(n < walk->cipher_blocksize)) {
 		desc->flags |= CRYPTO_TFM_RES_BAD_BLOCK_LEN;
-		return blkcipher_walk_done(desc, walk, -EINVAL);
+		return blkcipher_walk_unwind(desc, walk, -EINVAL);
 	}
 
 	bsize = min(walk->walk_blocksize, n);
-- 
Email: Herbert Xu <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt

  reply	other threads:[~2019-09-03  7:09 UTC|newest]

Thread overview: 37+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-08-21 14:32 [PATCH 00/17] crypto: arm/aes - XTS ciphertext stealing and other updates Ard Biesheuvel
2019-08-21 14:32 ` [PATCH 01/17] crypto: arm/aes - fix round key prototypes Ard Biesheuvel
2019-08-21 14:32 ` [PATCH 02/17] crypto: arm/aes-ce - yield the SIMD unit between scatterwalk steps Ard Biesheuvel
2019-08-21 14:32 ` [PATCH 03/17] crypto: arm/aes-ce - switch to 4x interleave Ard Biesheuvel
2019-08-21 14:32 ` [PATCH 04/17] crypto: arm/aes-ce - replace tweak mask literal with composition Ard Biesheuvel
2019-08-21 14:32 ` [PATCH 05/17] crypto: arm/aes-neonbs " Ard Biesheuvel
2019-08-21 14:32 ` [PATCH 06/17] crypto: arm64/aes-neonbs " Ard Biesheuvel
2019-08-21 14:32 ` [PATCH 07/17] crypto: arm64/aes-neon - limit exposed routines if faster driver is enabled Ard Biesheuvel
2019-08-21 14:32 ` [PATCH 08/17] crypto: skcipher - add the ability to abort a skcipher walk Ard Biesheuvel
2019-08-30  8:03   ` Herbert Xu
2019-08-31 18:01     ` Ard Biesheuvel
2019-09-03  6:54       ` crypto: skcipher - Unmap pages after an external error Herbert Xu
2019-09-03  7:05         ` crypto: ablkcipher " Herbert Xu
2019-09-03  7:09           ` Herbert Xu [this message]
2019-09-03 13:50         ` crypto: skcipher " Eric Biggers
2019-09-03 22:36           ` Herbert Xu
2019-09-05  5:22             ` Eric Biggers
2019-09-05  5:40               ` Herbert Xu
2019-09-06  1:57                 ` Eric Biggers
2019-09-06  2:15                   ` Herbert Xu
2019-09-06  3:13                     ` [v2 PATCH] " Herbert Xu
2019-09-07  0:52                       ` Ard Biesheuvel
2019-09-07  1:19                         ` Herbert Xu
2019-09-07  1:32                           ` Ard Biesheuvel
2019-09-07  1:56                             ` Herbert Xu
2019-09-07  2:14                               ` Ard Biesheuvel
2019-08-21 14:32 ` [PATCH 09/17] crypto: arm64/aes-cts-cbc-ce - performance tweak Ard Biesheuvel
2019-08-21 14:32 ` [PATCH 10/17] crypto: arm64/aes-cts-cbc - move request context data to the stack Ard Biesheuvel
2019-08-21 14:32 ` [PATCH 11/17] crypto: arm64/aes - implement support for XTS ciphertext stealing Ard Biesheuvel
2019-08-21 14:32 ` [PATCH 12/17] crypto: arm64/aes-neonbs - implement ciphertext stealing for XTS Ard Biesheuvel
2019-08-21 14:32 ` [PATCH 13/17] crypto: arm/aes-ce " Ard Biesheuvel
2019-08-21 14:32 ` [PATCH 14/17] crypto: arm/aes-neonbs " Ard Biesheuvel
2019-08-21 14:32 ` [PATCH 15/17] crypto: arm/aes-ce - implement ciphertext stealing for CBC Ard Biesheuvel
2019-09-30 16:32   ` Guenter Roeck
2019-09-30 18:19     ` Ard Biesheuvel
2019-08-21 14:32 ` [PATCH 16/17] crypto: testmgr - add test vectors for XTS ciphertext stealing Ard Biesheuvel
2019-08-21 14:32 ` [PATCH 17/17] crypto: testmgr - Add additional AES-XTS vectors for covering CTS Ard Biesheuvel

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20190903070919.GA10892@gondor.apana.org.au \
    --to=herbert@gondor.apana.org.au \
    --cc=ard.biesheuvel@linaro.org \
    --cc=ebiggers@kernel.org \
    --cc=linux-crypto@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).