]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blob - queue-4.19/crypto-morus-fix-handling-chunked-inputs.patch
997c8543cf20af1089bdc62aa2abd629558bc0ff
[thirdparty/kernel/stable-queue.git] / queue-4.19 / crypto-morus-fix-handling-chunked-inputs.patch
1 From d644f1c8746ed24f81075480f9e9cb3777ae8d65 Mon Sep 17 00:00:00 2001
2 From: Eric Biggers <ebiggers@google.com>
3 Date: Thu, 31 Jan 2019 23:51:37 -0800
4 Subject: crypto: morus - fix handling chunked inputs
5
6 From: Eric Biggers <ebiggers@google.com>
7
8 commit d644f1c8746ed24f81075480f9e9cb3777ae8d65 upstream.
9
10 The generic MORUS implementations all fail the improved AEAD tests
11 because they produce the wrong result with some data layouts. The issue
12 is that they assume that if the skcipher_walk API gives 'nbytes' not
13 aligned to the walksize (a.k.a. walk.stride), then it is the end of the
14 data. In fact, this can happen before the end. Fix them.
15
16 Fixes: 396be41f16fd ("crypto: morus - Add generic MORUS AEAD implementations")
17 Cc: <stable@vger.kernel.org> # v4.18+
18 Cc: Ondrej Mosnacek <omosnace@redhat.com>
19 Signed-off-by: Eric Biggers <ebiggers@google.com>
20 Reviewed-by: Ondrej Mosnacek <omosnace@redhat.com>
21 Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
22 Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
23
24 ---
25 crypto/morus1280.c | 13 +++++++------
26 crypto/morus640.c | 13 +++++++------
27 2 files changed, 14 insertions(+), 12 deletions(-)
28
29 --- a/crypto/morus1280.c
30 +++ b/crypto/morus1280.c
31 @@ -366,18 +366,19 @@ static void crypto_morus1280_process_cry
32 const struct morus1280_ops *ops)
33 {
34 struct skcipher_walk walk;
35 - u8 *dst;
36 - const u8 *src;
37
38 ops->skcipher_walk_init(&walk, req, false);
39
40 while (walk.nbytes) {
41 - src = walk.src.virt.addr;
42 - dst = walk.dst.virt.addr;
43 + unsigned int nbytes = walk.nbytes;
44
45 - ops->crypt_chunk(state, dst, src, walk.nbytes);
46 + if (nbytes < walk.total)
47 + nbytes = round_down(nbytes, walk.stride);
48
49 - skcipher_walk_done(&walk, 0);
50 + ops->crypt_chunk(state, walk.dst.virt.addr, walk.src.virt.addr,
51 + nbytes);
52 +
53 + skcipher_walk_done(&walk, walk.nbytes - nbytes);
54 }
55 }
56
57 --- a/crypto/morus640.c
58 +++ b/crypto/morus640.c
59 @@ -365,18 +365,19 @@ static void crypto_morus640_process_cryp
60 const struct morus640_ops *ops)
61 {
62 struct skcipher_walk walk;
63 - u8 *dst;
64 - const u8 *src;
65
66 ops->skcipher_walk_init(&walk, req, false);
67
68 while (walk.nbytes) {
69 - src = walk.src.virt.addr;
70 - dst = walk.dst.virt.addr;
71 + unsigned int nbytes = walk.nbytes;
72
73 - ops->crypt_chunk(state, dst, src, walk.nbytes);
74 + if (nbytes < walk.total)
75 + nbytes = round_down(nbytes, walk.stride);
76
77 - skcipher_walk_done(&walk, 0);
78 + ops->crypt_chunk(state, walk.dst.virt.addr, walk.src.virt.addr,
79 + nbytes);
80 +
81 + skcipher_walk_done(&walk, walk.nbytes - nbytes);
82 }
83 }
84