summaryrefslogtreecommitdiffstats
path: root/crypto
diff options
context:
space:
mode:
authorHerbert Xu <herbert@gondor.apana.org.au>2017-10-06 23:29:48 -0400
committerHerbert Xu <herbert@gondor.apana.org.au>2017-10-07 00:04:32 -0400
commit0cabf2af6f5ac3c88cb106c4e06087a5a39b8e1e (patch)
tree6d612f29ee44e877b4fb546898f729f135ac9900 /crypto
parent9039f3ef446e9ffa200200c934f049add9e58426 (diff)
crypto: skcipher - Fix crash on zero-length input
The skcipher walk interface doesn't handle zero-length input properly as the old blkcipher walk interface did. This is due to the fact that the length check is done too late. This patch moves the length check forward so that it does the right thing. Fixes: b286d8b1a690 ("crypto: skcipher - Add skcipher walk...") Cc: <stable@vger.kernel.org> Reported-by: Stephan Müller <smueller@chronox.de> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Diffstat (limited to 'crypto')
-rw-r--r--crypto/skcipher.c17
1 files changed, 11 insertions, 6 deletions
diff --git a/crypto/skcipher.c b/crypto/skcipher.c
index 4faa0fd53b0c..d5692e35fab1 100644
--- a/crypto/skcipher.c
+++ b/crypto/skcipher.c
@@ -426,14 +426,9 @@ static int skcipher_copy_iv(struct skcipher_walk *walk)
426 426
427static int skcipher_walk_first(struct skcipher_walk *walk) 427static int skcipher_walk_first(struct skcipher_walk *walk)
428{ 428{
429 walk->nbytes = 0;
430
431 if (WARN_ON_ONCE(in_irq())) 429 if (WARN_ON_ONCE(in_irq()))
432 return -EDEADLK; 430 return -EDEADLK;
433 431
434 if (unlikely(!walk->total))
435 return 0;
436
437 walk->buffer = NULL; 432 walk->buffer = NULL;
438 if (unlikely(((unsigned long)walk->iv & walk->alignmask))) { 433 if (unlikely(((unsigned long)walk->iv & walk->alignmask))) {
439 int err = skcipher_copy_iv(walk); 434 int err = skcipher_copy_iv(walk);
@@ -452,10 +447,15 @@ static int skcipher_walk_skcipher(struct skcipher_walk *walk,
452{ 447{
453 struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req); 448 struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
454 449
450 walk->total = req->cryptlen;
451 walk->nbytes = 0;
452
453 if (unlikely(!walk->total))
454 return 0;
455
455 scatterwalk_start(&walk->in, req->src); 456 scatterwalk_start(&walk->in, req->src);
456 scatterwalk_start(&walk->out, req->dst); 457 scatterwalk_start(&walk->out, req->dst);
457 458
458 walk->total = req->cryptlen;
459 walk->iv = req->iv; 459 walk->iv = req->iv;
460 walk->oiv = req->iv; 460 walk->oiv = req->iv;
461 461
@@ -509,6 +509,11 @@ static int skcipher_walk_aead_common(struct skcipher_walk *walk,
509 struct crypto_aead *tfm = crypto_aead_reqtfm(req); 509 struct crypto_aead *tfm = crypto_aead_reqtfm(req);
510 int err; 510 int err;
511 511
512 walk->nbytes = 0;
513
514 if (unlikely(!walk->total))
515 return 0;
516
512 walk->flags &= ~SKCIPHER_WALK_PHYS; 517 walk->flags &= ~SKCIPHER_WALK_PHYS;
513 518
514 scatterwalk_start(&walk->in, req->src); 519 scatterwalk_start(&walk->in, req->src);