summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJussi Kivilinna <jussi.kivilinna@iki.fi>2021-02-03 18:11:46 +0200
committerJussi Kivilinna <jussi.kivilinna@iki.fi>2021-02-03 18:30:03 +0200
commit24af2a55d862d45fe3aef6b5626a52d9bb0fb17e (patch)
treeeabb994c5860bc9bf2ae3d0d9bad7035eb0831cb
parent289543544e41cd5fe90352c5c7548ac09da533cc (diff)
downloadlibgcrypt-24af2a55d862d45fe3aef6b5626a52d9bb0fb17e.tar.gz
sha256-avx2: fix reading beyond end of input buffer
* 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@gmail.com> Signed-off-by: Jussi Kivilinna <jussi.kivilinna@iki.fi>
-rw-r--r--cipher/sha256-avx2-bmi2-amd64.S7
-rw-r--r--tests/basic.c20
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)