Skip to content

Commit

Permalink
crypto: morus - fix handling chunked inputs
Browse files Browse the repository at this point in the history
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: 396be41 ("crypto: morus - Add generic MORUS AEAD implementations")
Cc: <[email protected]> # v4.18+
Cc: Ondrej Mosnacek <[email protected]>
Signed-off-by: Eric Biggers <[email protected]>
Reviewed-by: Ondrej Mosnacek <[email protected]>
Signed-off-by: Herbert Xu <[email protected]>
  • Loading branch information
ebiggers authored and herbertx committed Feb 8, 2019
1 parent 0f533e6 commit d644f1c
Show file tree
Hide file tree
Showing 2 changed files with 14 additions and 12 deletions.
13 changes: 7 additions & 6 deletions crypto/morus1280.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
}

Expand Down
13 changes: 7 additions & 6 deletions crypto/morus640.c
Original file line number Diff line number Diff line change
Expand Up @@ -361,18 +361,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);
}
}

Expand Down

0 comments on commit d644f1c

Please sign in to comment.