diff options
author | Jussi Kivilinna <jussi.kivilinna@iki.fi> | 2021-01-28 22:13:14 +0200 |
---|---|---|
committer | Jussi Kivilinna <jussi.kivilinna@iki.fi> | 2021-01-29 09:43:33 +0200 |
commit | 512c0c75276949f13b6373b5c04f7065af750b08 (patch) | |
tree | 5c3dd4e49bba1f8b1a2259a1dea754a0c696e07f | |
parent | aa3f595341eb263980210776c7fe377b2ed24c5e (diff) | |
download | libgcrypt-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.c | 7 | ||||
-rw-r--r-- | tests/basic.c | 7 |
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 { |