crypto: hash - Zap unaligned buffers
Some unaligned buffers on the stack weren't zapped properly which may cause secret data to be leaked. This patch fixes them by doing a zero memset. It is also possible for us to place random kernel stack contents in the digest buffer if a digest operation fails. This is fixed by only copying if the operation succeeded. Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
This commit is contained in:
Родитель
500b3e3c3d
Коммит
8c32c516eb
|
@ -152,8 +152,7 @@ static int ahash_setkey_unaligned(struct crypto_ahash *tfm, const u8 *key,
|
||||||
alignbuffer = (u8 *)ALIGN((unsigned long)buffer, alignmask + 1);
|
alignbuffer = (u8 *)ALIGN((unsigned long)buffer, alignmask + 1);
|
||||||
memcpy(alignbuffer, key, keylen);
|
memcpy(alignbuffer, key, keylen);
|
||||||
ret = ahash->setkey(tfm, alignbuffer, keylen);
|
ret = ahash->setkey(tfm, alignbuffer, keylen);
|
||||||
memset(alignbuffer, 0, keylen);
|
kzfree(buffer);
|
||||||
kfree(buffer);
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -45,8 +45,7 @@ static int shash_setkey_unaligned(struct crypto_shash *tfm, const u8 *key,
|
||||||
alignbuffer = (u8 *)ALIGN((unsigned long)buffer, alignmask + 1);
|
alignbuffer = (u8 *)ALIGN((unsigned long)buffer, alignmask + 1);
|
||||||
memcpy(alignbuffer, key, keylen);
|
memcpy(alignbuffer, key, keylen);
|
||||||
err = shash->setkey(tfm, alignbuffer, keylen);
|
err = shash->setkey(tfm, alignbuffer, keylen);
|
||||||
memset(alignbuffer, 0, keylen);
|
kzfree(buffer);
|
||||||
kfree(buffer);
|
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -79,13 +78,16 @@ static int shash_update_unaligned(struct shash_desc *desc, const u8 *data,
|
||||||
((unsigned long)data & alignmask);
|
((unsigned long)data & alignmask);
|
||||||
u8 buf[shash_align_buffer_size(unaligned_len, alignmask)]
|
u8 buf[shash_align_buffer_size(unaligned_len, alignmask)]
|
||||||
__attribute__ ((aligned));
|
__attribute__ ((aligned));
|
||||||
|
int err;
|
||||||
|
|
||||||
if (unaligned_len > len)
|
if (unaligned_len > len)
|
||||||
unaligned_len = len;
|
unaligned_len = len;
|
||||||
|
|
||||||
memcpy(buf, data, unaligned_len);
|
memcpy(buf, data, unaligned_len);
|
||||||
|
err = shash->update(desc, buf, unaligned_len);
|
||||||
|
memset(buf, 0, unaligned_len);
|
||||||
|
|
||||||
return shash->update(desc, buf, unaligned_len) ?:
|
return err ?:
|
||||||
shash->update(desc, data + unaligned_len, len - unaligned_len);
|
shash->update(desc, data + unaligned_len, len - unaligned_len);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -114,7 +116,13 @@ static int shash_final_unaligned(struct shash_desc *desc, u8 *out)
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
err = shash->final(desc, buf);
|
err = shash->final(desc, buf);
|
||||||
|
if (err)
|
||||||
|
goto out;
|
||||||
|
|
||||||
memcpy(out, buf, ds);
|
memcpy(out, buf, ds);
|
||||||
|
|
||||||
|
out:
|
||||||
|
memset(buf, 0, ds);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Загрузка…
Ссылка в новой задаче