summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEric Biggers <ebiggers@google.com>2019-01-31 23:51:37 -0800
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2019-03-23 20:11:15 +0100
commit9cbfb0a8d1afb0b47327fe0e0956c106070abf64 (patch)
tree15569ba63739ac14d5e06760acd5c02324cb445f
parentc850ff289c4ea283f147157945297a96ed9cdae0 (diff)
downloadblackbird-obmc-linux-9cbfb0a8d1afb0b47327fe0e0956c106070abf64.tar.gz
blackbird-obmc-linux-9cbfb0a8d1afb0b47327fe0e0956c106070abf64.zip
crypto: morus - fix handling chunked inputs
commit d644f1c8746ed24f81075480f9e9cb3777ae8d65 upstream. The generic MORUS implementations all fail the improved AEAD tests because they produce the wrong result with some data layouts. The issue is that they assume that if the skcipher_walk API gives 'nbytes' not aligned to the walksize (a.k.a. walk.stride), then it is the end of the data. In fact, this can happen before the end. Fix them. Fixes: 396be41f16fd ("crypto: morus - Add generic MORUS AEAD implementations") Cc: <stable@vger.kernel.org> # v4.18+ Cc: Ondrej Mosnacek <omosnace@redhat.com> Signed-off-by: Eric Biggers <ebiggers@google.com> Reviewed-by: Ondrej Mosnacek <omosnace@redhat.com> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--crypto/morus1280.c13
-rw-r--r--crypto/morus640.c13
2 files changed, 14 insertions, 12 deletions
diff --git a/crypto/morus1280.c b/crypto/morus1280.c
index 3889c188f266..b83576b4eb55 100644
--- a/crypto/morus1280.c
+++ b/crypto/morus1280.c
@@ -366,18 +366,19 @@ static void crypto_morus1280_process_crypt(struct morus1280_state *state,
const struct morus1280_ops *ops)
{
struct skcipher_walk walk;
- u8 *dst;
- const u8 *src;
ops->skcipher_walk_init(&walk, req, false);
while (walk.nbytes) {
- src = walk.src.virt.addr;
- dst = walk.dst.virt.addr;
+ unsigned int nbytes = walk.nbytes;
- ops->crypt_chunk(state, dst, src, walk.nbytes);
+ if (nbytes < walk.total)
+ nbytes = round_down(nbytes, walk.stride);
- skcipher_walk_done(&walk, 0);
+ ops->crypt_chunk(state, walk.dst.virt.addr, walk.src.virt.addr,
+ nbytes);
+
+ skcipher_walk_done(&walk, walk.nbytes - nbytes);
}
}
diff --git a/crypto/morus640.c b/crypto/morus640.c
index da06ec2f6a80..b6a477444f6d 100644
--- a/crypto/morus640.c
+++ b/crypto/morus640.c
@@ -365,18 +365,19 @@ static void crypto_morus640_process_crypt(struct morus640_state *state,
const struct morus640_ops *ops)
{
struct skcipher_walk walk;
- u8 *dst;
- const u8 *src;
ops->skcipher_walk_init(&walk, req, false);
while (walk.nbytes) {
- src = walk.src.virt.addr;
- dst = walk.dst.virt.addr;
+ unsigned int nbytes = walk.nbytes;
- ops->crypt_chunk(state, dst, src, walk.nbytes);
+ if (nbytes < walk.total)
+ nbytes = round_down(nbytes, walk.stride);
- skcipher_walk_done(&walk, 0);
+ ops->crypt_chunk(state, walk.dst.virt.addr, walk.src.virt.addr,
+ nbytes);
+
+ skcipher_walk_done(&walk, walk.nbytes - nbytes);
}
}
OpenPOWER on IntegriCloud