summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJussi Kivilinna <jussi.kivilinna@iki.fi>2021-01-28 22:13:14 +0200
committerJussi Kivilinna <jussi.kivilinna@iki.fi>2021-01-29 09:43:33 +0200
commit512c0c75276949f13b6373b5c04f7065af750b08 (patch)
tree5c3dd4e49bba1f8b1a2259a1dea754a0c696e07f
parentaa3f595341eb263980210776c7fe377b2ed24c5e (diff)
downloadlibgcrypt-512c0c75276949f13b6373b5c04f7065af750b08.tar.gz
hash-common: fix heap overflow when writing more data after final
* tests/basic.c (check_one_md): Test writing to digest after read. * cipher/hash-common.c (_gcry_md_block_write): Reset 'hd->count' if greater than blocksize. -- '_gcry_md_block_write' did not expect 'hd->count' being greater than digest blocksize. However digest final function may set 'hd->count' to larger value. Now, if write is called after final function and 'hd->count' gets too large value, 'copylen' parameter to buf_cpy may have value larger than size of 'hd->buf' and cause heap overflow. Reported-by: Tavis Ormandy <taviso@gmail.com> Signed-off-by: Jussi Kivilinna <jussi.kivilinna@iki.fi>
-rw-r--r--cipher/hash-common.c7
-rw-r--r--tests/basic.c7
2 files changed, 14 insertions, 0 deletions
diff --git a/cipher/hash-common.c b/cipher/hash-common.c
index ab486f06..ed2d7cac 100644
--- a/cipher/hash-common.c
+++ b/cipher/hash-common.c
@@ -134,6 +134,13 @@ _gcry_md_block_write (void *context, const void *inbuf_arg, size_t inlen)
if (!hd->bwrite)
return;
+ if (hd->count > blocksize)
+ {
+ /* This happens only when gcry_md_write is called after final.
+ * Writing after final is used for mitigating timing attacks. */
+ hd->count = 0;
+ }
+
while (hd->count)
{
if (hd->count == blocksize) /* Flush the buffer. */
diff --git a/tests/basic.c b/tests/basic.c
index 8b333bae..c54de78b 100644
--- a/tests/basic.c
+++ b/tests/basic.c
@@ -10223,6 +10223,8 @@ check_one_md (int algo, const char *data, int len, const char *expect, int elen,
if (!xof)
{
+ static const char buf[128];
+
clutter_vector_registers();
p = gcry_md_read (hd2, algo);
@@ -10238,6 +10240,11 @@ check_one_md (int algo, const char *data, int len, const char *expect, int elen,
fail ("algo %d, digest mismatch\n", algo);
}
+
+ /* Write after final/read is allowed for timing attack mitigation
+ * purposes. Try writing and see if we catch fire. */
+ clutter_vector_registers();
+ gcry_md_write (hd2, buf, sizeof(buf));
}
else
{