summaryrefslogtreecommitdiffstats
path: root/crypto/morus1280.c
diff options
context:
space:
mode:
authorEric Biggers2019-02-01 08:51:37 +0100
committerHerbert Xu2019-02-08 08:30:08 +0100
commitd644f1c8746ed24f81075480f9e9cb3777ae8d65 (patch)
tree031ca8c64d91586823c8e8a4360a58abdfa00297 /crypto/morus1280.c
parentcrypto: aegis - fix handling chunked inputs (diff)
downloadkernel-qcow2-linux-d644f1c8746ed24f81075480f9e9cb3777ae8d65.tar.gz
kernel-qcow2-linux-d644f1c8746ed24f81075480f9e9cb3777ae8d65.tar.xz
kernel-qcow2-linux-d644f1c8746ed24f81075480f9e9cb3777ae8d65.zip
crypto: morus - fix handling chunked inputs
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>
Diffstat (limited to 'crypto/morus1280.c')
-rw-r--r--crypto/morus1280.c13
1 files changed, 7 insertions, 6 deletions
diff --git a/crypto/morus1280.c b/crypto/morus1280.c
index 78ba09db7328..0747732d5b78 100644
--- a/crypto/morus1280.c
+++ b/crypto/morus1280.c
@@ -362,18 +362,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);
}
}