diff options
author | Werner Koch <wk@gnupg.org> | 2013-11-14 23:40:41 +0100 |
---|---|---|
committer | Werner Koch <wk@gnupg.org> | 2013-11-14 23:40:41 +0100 |
commit | c43a8c0d81a711161f7a81b24ef7c33a1353eee0 (patch) | |
tree | 79ba394352274bd7fe05b3ae8cc38c6d66961ed9 /cipher/tiger.c | |
parent | 7d91e99bcd30a463dd4faed014b8521a663d8316 (diff) | |
download | libgcrypt-c43a8c0d81a711161f7a81b24ef7c33a1353eee0.tar.gz |
md: Fix hashing for data >= 256 GB
* cipher/hash-common.h (gcry_md_block_ctx): Add "nblocks_high".
* cipher/hash-common.c (_gcry_md_block_write): Bump NBLOCKS_HIGH.
* cipher/md4.c (md4_init, md4_final): Take care of NBLOCKS_HIGH.
* cipher/md5.c (md5_init, md5_final): Ditto.
* cipher/rmd160.c (_gcry_rmd160_init, rmd160_final): Ditto.
* cipher/sha1.c (sha1_init, sha1_final): Ditto.
* cipher/sha256.c (sha256_init, sha224_init, sha256_final): Ditto.
* cipher/sha512.c (sha512_init, sha384_init, sha512_final): Ditto.
* cipher/tiger.c (do_init, tiger_final): Ditto.
* cipher/whirlpool.c (whirlpool_final): Ditto.
* cipher/md.c (gcry_md_algo_info): Add GCRYCTL_SELFTEST.
(_gcry_md_selftest): Return "not implemented" as required.
* tests/hashtest.c: New.
* tests/genhashdata.c: New.
* tests/Makefile.am (TESTS): Add hashtest.
(noinst_PROGRAMS): Add genhashdata
--
Problem found by Denis Corbin and analyzed by Yuriy Kaminskiy.
sha512 and whirlpool should not have this problem because they use 64
bit types for counting the blocks. However, a similar fix has been
employed to allow for really huge sizes - despite that it will be very
hard to test them.
The test vectors have been produced by sha{1,224,256}sum and the
genhashdata tool. A sequence of 'a' is used for them because a test
using one million 'a' is commonly used for test vectors. More test
vectors are required. Running the large tests needs to be done
manual for now:
./hashtest --gigs 256
tests all algorithms,
./hashtest --gigs 256 sha1 sha224 sha256
only the given ones. A configure option to include these test in the
standard regression suite will be useful. The tests will take looong.
Signed-off-by: Werner Koch <wk@gnupg.org>
Diffstat (limited to 'cipher/tiger.c')
-rw-r--r-- | cipher/tiger.c | 10 |
1 files changed, 8 insertions, 2 deletions
diff --git a/cipher/tiger.c b/cipher/tiger.c index a70a3f2c..9b8d0ef3 100644 --- a/cipher/tiger.c +++ b/cipher/tiger.c @@ -602,6 +602,7 @@ do_init (void *context, int variant) hd->c = 0xf096a5b4c3b2e187LL; hd->bctx.nblocks = 0; + hd->bctx.nblocks_high = 0; hd->bctx.count = 0; hd->bctx.blocksize = 64; hd->bctx.bwrite = transform; @@ -735,7 +736,7 @@ static void tiger_final( void *context ) { TIGER_CONTEXT *hd = context; - u32 t, msb, lsb; + u32 t, th, msb, lsb; byte *p; unsigned int burn; byte pad = hd->variant == 2? 0x80 : 0x01; @@ -743,9 +744,14 @@ tiger_final( void *context ) _gcry_md_block_write(hd, NULL, 0); /* flush */; t = hd->bctx.nblocks; + if (sizeof t == sizeof hd->bctx.nblocks) + th = hd->bctx.nblocks_high; + else + th = hd->bctx.nblocks >> 32; + /* multiply by 64 to make a byte count */ lsb = t << 6; - msb = t >> 26; + msb = (th << 6) | (t >> 26); /* add the count */ t = lsb; if( (lsb += hd->bctx.count) < t ) |