summaryrefslogtreecommitdiff
path: root/crypto/aegis128.c
diff options
context:
space:
mode:
authorEric Biggers <ebiggers@google.com>2019-01-31 23:51:36 -0800
committerHerbert Xu <herbert@gondor.apana.org.au>2019-02-08 15:30:08 +0800
commitd23089c20adddd2d3ba409198719493695d56096 (patch)
tree38a031e098c9ce221feee65ab7bab9f6c3d7f2ae /crypto/aegis128.c
parent953d7f87e3ef048eccdbfcaf3dfc25caba2b8763 (diff)
downloadlinux-crypto-d23089c20adddd2d3ba409198719493695d56096.tar.gz
linux-crypto-d23089c20adddd2d3ba409198719493695d56096.zip
crypto: aegis - fix handling chunked inputs
The generic AEGIS 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: cc695b2e62a6 ("crypto: aegis - Add generic AEGIS 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/aegis128.c')
-rw-r--r--crypto/aegis128.c14
1 files changed, 7 insertions, 7 deletions
diff --git a/crypto/aegis128.c b/crypto/aegis128.c
index 96e078a8..3718a834 100644
--- a/crypto/aegis128.c
+++ b/crypto/aegis128.c
@@ -286,19 +286,19 @@ static void crypto_aegis128_process_crypt(struct aegis_state *state,
const struct aegis128_ops *ops)
{
struct skcipher_walk walk;
- u8 *src, *dst;
- unsigned int chunksize;
ops->skcipher_walk_init(&walk, req, false);
while (walk.nbytes) {
- src = walk.src.virt.addr;
- dst = walk.dst.virt.addr;
- chunksize = walk.nbytes;
+ unsigned int nbytes = walk.nbytes;
- ops->crypt_chunk(state, dst, src, chunksize);
+ 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);
}
}