[PATCH] sha256-avx2: fix reading beyond end of input buffer

classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view
|

[PATCH] sha256-avx2: fix reading beyond end of input buffer

Jussi Kivilinna-2
* 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 <[hidden email]>
Signed-off-by: Jussi Kivilinna <[hidden email]>
---
 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


_______________________________________________
Gcrypt-devel mailing list
[hidden email]
http://lists.gnupg.org/mailman/listinfo/gcrypt-devel