[PATCH] sha256-avx2: fix reading beyond end of input buffer
Jussi Kivilinna
jussi.kivilinna at iki.fi
Wed Feb 3 17:25:56 CET 2021
* cipher/sha256-avx2-bmi2-amd64.S
(_gcry_sha256_transform_amd64_avx2): Use 'last block' code path if
input length is only one block.
* tests/basic.c (check_one_md_final): Use dynamic allocated buffer
so that in future similar access errors get detected by
tests/basic + valgrind.
--
Reported-by: Guido Vranken <guidovranken at gmail.com>
Signed-off-by: Jussi Kivilinna <jussi.kivilinna at iki.fi>
---
cipher/sha256-avx2-bmi2-amd64.S | 7 +++++++
tests/basic.c | 20 +++++++++++++++-----
2 files changed, 22 insertions(+), 5 deletions(-)
diff --git a/cipher/sha256-avx2-bmi2-amd64.S b/cipher/sha256-avx2-bmi2-amd64.S
index faefba17..d130dd4a 100644
--- a/cipher/sha256-avx2-bmi2-amd64.S
+++ b/cipher/sha256-avx2-bmi2-amd64.S
@@ -285,6 +285,11 @@ _gcry_sha256_transform_amd64_avx2:
lea NUM_BLKS, [NUM_BLKS + INP - 64] /* pointer to last block */
mov [rsp + _INP_END], NUM_BLKS
+ /* Check if only one block of input. Note: Loading initial digest
+ * only uses 'mov' instruction and does not change condition
+ * flags. */
+ cmp NUM_BLKS, INP
+
/* ; load initial digest */
mov a,[4*0 + CTX]
mov b,[4*1 + CTX]
@@ -297,6 +302,8 @@ _gcry_sha256_transform_amd64_avx2:
mov [rsp + _CTX], CTX
+ je .Ldo_last_block
+
.Loop0:
lea TBL, [.LK256 ADD_RIP]
diff --git a/tests/basic.c b/tests/basic.c
index c54de78b..b4757d9c 100644
--- a/tests/basic.c
+++ b/tests/basic.c
@@ -10478,7 +10478,8 @@ check_one_md_multi (int algo, const char *data, int len, const char *expect)
static void
check_one_md_final(int algo, const char *expect, unsigned int expectlen)
{
- char inbuf[288 + 1];
+ const unsigned int max_inbuf_len = 288 + 1;
+ char *inbuf;
char xorbuf[64];
char digest[64];
unsigned int mdlen;
@@ -10499,16 +10500,25 @@ check_one_md_final(int algo, const char *expect, unsigned int expectlen)
return;
}
- for (i = 0; i < sizeof(inbuf); i++)
- inbuf[i] = i;
-
clutter_vector_registers();
gcry_md_hash_buffer (algo, xorbuf, NULL, 0);
- for (i = 1; i < sizeof(inbuf); i++)
+ for (i = 1; i < max_inbuf_len; i++)
{
+ inbuf = xmalloc(i);
+ if (!inbuf)
+ {
+ fail ("out-of-memory\n");
+ return;
+ }
+
+ for (j = 0; j < i; j++)
+ inbuf[j] = j;
+
gcry_md_hash_buffer (algo, digest, inbuf, i);
for (j = 0; j < expectlen; j++)
xorbuf[j] ^= digest[j];
+
+ xfree (inbuf);
}
if (memcmp(expect, xorbuf, expectlen) != 0)
--
2.27.0
More information about the Gcrypt-devel
mailing list