]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blob - queue-4.14/crypto-ahash-fix-another-early-termination-in-hash-walk.patch
4.14-stable patches
[thirdparty/kernel/stable-queue.git] / queue-4.14 / crypto-ahash-fix-another-early-termination-in-hash-walk.patch
1 From 77568e535af7c4f97eaef1e555bf0af83772456c Mon Sep 17 00:00:00 2001
2 From: Eric Biggers <ebiggers@google.com>
3 Date: Thu, 31 Jan 2019 23:51:41 -0800
4 Subject: crypto: ahash - fix another early termination in hash walk
5
6 From: Eric Biggers <ebiggers@google.com>
7
8 commit 77568e535af7c4f97eaef1e555bf0af83772456c upstream.
9
10 Hash algorithms with an alignmask set, e.g. "xcbc(aes-aesni)" and
11 "michael_mic", fail the improved hash tests because they sometimes
12 produce the wrong digest. The bug is that in the case where a
13 scatterlist element crosses pages, not all the data is actually hashed
14 because the scatterlist walk terminates too early. This happens because
15 the 'nbytes' variable in crypto_hash_walk_done() is assigned the number
16 of bytes remaining in the page, then later interpreted as the number of
17 bytes remaining in the scatterlist element. Fix it.
18
19 Fixes: 900a081f6912 ("crypto: ahash - Fix early termination in hash walk")
20 Cc: stable@vger.kernel.org
21 Signed-off-by: Eric Biggers <ebiggers@google.com>
22 Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
23 Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
24
25 ---
26 crypto/ahash.c | 14 +++++++-------
27 1 file changed, 7 insertions(+), 7 deletions(-)
28
29 --- a/crypto/ahash.c
30 +++ b/crypto/ahash.c
31 @@ -86,17 +86,17 @@ static int hash_walk_new_entry(struct cr
32 int crypto_hash_walk_done(struct crypto_hash_walk *walk, int err)
33 {
34 unsigned int alignmask = walk->alignmask;
35 - unsigned int nbytes = walk->entrylen;
36
37 walk->data -= walk->offset;
38
39 - if (nbytes && walk->offset & alignmask && !err) {
40 - walk->offset = ALIGN(walk->offset, alignmask + 1);
41 - nbytes = min(nbytes,
42 - ((unsigned int)(PAGE_SIZE)) - walk->offset);
43 - walk->entrylen -= nbytes;
44 + if (walk->entrylen && (walk->offset & alignmask) && !err) {
45 + unsigned int nbytes;
46
47 + walk->offset = ALIGN(walk->offset, alignmask + 1);
48 + nbytes = min(walk->entrylen,
49 + (unsigned int)(PAGE_SIZE - walk->offset));
50 if (nbytes) {
51 + walk->entrylen -= nbytes;
52 walk->data += walk->offset;
53 return nbytes;
54 }
55 @@ -116,7 +116,7 @@ int crypto_hash_walk_done(struct crypto_
56 if (err)
57 return err;
58
59 - if (nbytes) {
60 + if (walk->entrylen) {
61 walk->offset = 0;
62 walk->pg++;
63 return hash_walk_next(walk);