Skip to content

Commit

Permalink
crypto: aegis - fix handling chunked inputs
Browse files Browse the repository at this point in the history
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: f606a88 ("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>
  • Loading branch information
ebiggers authored and herbertx committed Feb 8, 2019
1 parent 42e95d1 commit 0f533e6
Show file tree
Hide file tree
Showing 3 changed files with 21 additions and 21 deletions.
14 changes: 7 additions & 7 deletions crypto/aegis128.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
}

Expand Down
14 changes: 7 additions & 7 deletions crypto/aegis128l.c
Original file line number Diff line number Diff line change
Expand Up @@ -349,19 +349,19 @@ static void crypto_aegis128l_process_crypt(struct aegis_state *state,
const struct aegis128l_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);
}
}

Expand Down
14 changes: 7 additions & 7 deletions crypto/aegis256.c
Original file line number Diff line number Diff line change
Expand Up @@ -299,19 +299,19 @@ static void crypto_aegis256_process_crypt(struct aegis_state *state,
const struct aegis256_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);
}
}

Expand Down

0 comments on commit 0f533e6

Please sign in to comment.