diff options
author | Jussi Kivilinna <jussi.kivilinna@iki.fi> | 2021-02-03 18:11:46 +0200 |
---|---|---|
committer | Jussi Kivilinna <jussi.kivilinna@iki.fi> | 2021-02-03 18:30:03 +0200 |
commit | 24af2a55d862d45fe3aef6b5626a52d9bb0fb17e (patch) | |
tree | eabb994c5860bc9bf2ae3d0d9bad7035eb0831cb | |
parent | 289543544e41cd5fe90352c5c7548ac09da533cc (diff) | |
download | libgcrypt-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.S | 7 | ||||
-rw-r--r-- | 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) |