crypto: ahash - fix another early termination in hash walk
Hash algorithms with an alignmask set, e.g. "xcbc(aes-aesni)" and
"michael_mic", fail the improved hash tests because they sometimes
produce the wrong digest. The bug is that in the case where a
scatterlist element crosses pages, not all the data is actually hashed
because the scatterlist walk terminates too early. This happens because
the 'nbytes' variable in crypto_hash_walk_done() is assigned the number
of bytes remaining in the page, then later interpreted as the number of
bytes remaining in the scatterlist element. Fix it.
Fixes: 900a081f69
("crypto: ahash - Fix early termination in hash walk")
Cc: stable@vger.kernel.org
Signed-off-by: Eric Biggers <ebiggers@google.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
This commit is contained in:
parent
3af3496395
commit
77568e535a
|
@ -86,17 +86,17 @@ static int hash_walk_new_entry(struct crypto_hash_walk *walk)
|
||||||
int crypto_hash_walk_done(struct crypto_hash_walk *walk, int err)
|
int crypto_hash_walk_done(struct crypto_hash_walk *walk, int err)
|
||||||
{
|
{
|
||||||
unsigned int alignmask = walk->alignmask;
|
unsigned int alignmask = walk->alignmask;
|
||||||
unsigned int nbytes = walk->entrylen;
|
|
||||||
|
|
||||||
walk->data -= walk->offset;
|
walk->data -= walk->offset;
|
||||||
|
|
||||||
if (nbytes && walk->offset & alignmask && !err) {
|
if (walk->entrylen && (walk->offset & alignmask) && !err) {
|
||||||
walk->offset = ALIGN(walk->offset, alignmask + 1);
|
unsigned int nbytes;
|
||||||
nbytes = min(nbytes,
|
|
||||||
((unsigned int)(PAGE_SIZE)) - walk->offset);
|
|
||||||
walk->entrylen -= nbytes;
|
|
||||||
|
|
||||||
|
walk->offset = ALIGN(walk->offset, alignmask + 1);
|
||||||
|
nbytes = min(walk->entrylen,
|
||||||
|
(unsigned int)(PAGE_SIZE - walk->offset));
|
||||||
if (nbytes) {
|
if (nbytes) {
|
||||||
|
walk->entrylen -= nbytes;
|
||||||
walk->data += walk->offset;
|
walk->data += walk->offset;
|
||||||
return nbytes;
|
return nbytes;
|
||||||
}
|
}
|
||||||
|
@ -116,7 +116,7 @@ int crypto_hash_walk_done(struct crypto_hash_walk *walk, int err)
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
if (nbytes) {
|
if (walk->entrylen) {
|
||||||
walk->offset = 0;
|
walk->offset = 0;
|
||||||
walk->pg++;
|
walk->pg++;
|
||||||
return hash_walk_next(walk);
|
return hash_walk_next(walk);
|
||||||
|
|
Loading…
Reference in New Issue