diff options
author | Jussi Kivilinna <jussi.kivilinna@iki.fi> | 2019-05-09 21:43:52 +0300 |
---|---|---|
committer | Jussi Kivilinna <jussi.kivilinna@iki.fi> | 2019-05-09 21:43:52 +0300 |
commit | 15592cd52f543aadb2fab8f6c112c68075309ad6 (patch) | |
tree | a5db20119319f0951b16eb71e582453a51eab580 | |
parent | da6cd4fea30f79cf9d8f9b2f1c6daf3aea39fa9c (diff) | |
download | libgcrypt-15592cd52f543aadb2fab8f6c112c68075309ad6.tar.gz |
Fix message digest final function for MD4, MD5 and RMD160
* cipher/md4.c (md4_final): Use buffer offset '64 + 56' for bit count
on 'need one extra block' path.
* cipher/md5.c (md5_final): Ditto.
* cipher/rmd160.c (rmd160_final): Ditto.
* tests/basic.c (check_one_md_final): New.
(check_digest): Add new '*' test vectors and handle them with
check_one_md_final.
--
This commit fixes bug introduced with commit "Optimizations for
digest final functions" e76cd0e2b1f6025c1319576a5848815d1d231aeb
to MD4, MD5 and RMD160 where digest ended up being wrong for input
message sizes 64*x+56..64. Patch also adds new test case that runs
message digest algorithms with different message lengths from 0 to
289.
Reported-by: Guido Vranken <guidovranken@gmail.com>
Signed-off-by: Jussi Kivilinna <jussi.kivilinna@iki.fi>
-rw-r--r-- | cipher/md4.c | 4 | ||||
-rw-r--r-- | cipher/md5.c | 4 | ||||
-rw-r--r-- | cipher/rmd160.c | 4 | ||||
-rw-r--r-- | tests/basic.c | 199 |
4 files changed, 205 insertions, 6 deletions
diff --git a/cipher/md4.c b/cipher/md4.c index f6258893..b75bc5e6 100644 --- a/cipher/md4.c +++ b/cipher/md4.c @@ -252,8 +252,8 @@ md4_final( void *context ) hd->bctx.count = 64 + 56; /* append the 64 bit count */ - buf_put_le32(hd->bctx.buf + 56, lsb); - buf_put_le32(hd->bctx.buf + 60, msb); + buf_put_le32(hd->bctx.buf + 64 + 56, lsb); + buf_put_le32(hd->bctx.buf + 64 + 60, msb); burn = transform (hd, hd->bctx.buf, 2); } diff --git a/cipher/md5.c b/cipher/md5.c index 67511ba0..94fcdf03 100644 --- a/cipher/md5.c +++ b/cipher/md5.c @@ -276,8 +276,8 @@ md5_final( void *context) hd->bctx.count = 64 + 56; /* append the 64 bit count */ - buf_put_le32(hd->bctx.buf + 56, lsb); - buf_put_le32(hd->bctx.buf + 60, msb); + buf_put_le32(hd->bctx.buf + 64 + 56, lsb); + buf_put_le32(hd->bctx.buf + 64 + 60, msb); burn = transform (hd, hd->bctx.buf, 2); } diff --git a/cipher/rmd160.c b/cipher/rmd160.c index f15eec22..24210a07 100644 --- a/cipher/rmd160.c +++ b/cipher/rmd160.c @@ -449,8 +449,8 @@ rmd160_final( void *context ) hd->bctx.count = 64 + 56; /* append the 64 bit count */ - buf_put_le32(hd->bctx.buf + 56, lsb); - buf_put_le32(hd->bctx.buf + 60, msb); + buf_put_le32(hd->bctx.buf + 64 + 56, lsb); + buf_put_le32(hd->bctx.buf + 64 + 60, msb); burn = transform (hd, hd->bctx.buf, 2); } diff --git a/tests/basic.c b/tests/basic.c index 55a8b72f..31595d0b 100644 --- a/tests/basic.c +++ b/tests/basic.c @@ -8593,6 +8593,56 @@ 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]; + char xorbuf[64]; + char digest[64]; + unsigned int mdlen; + int i, j; + + mdlen = gcry_md_get_algo_dlen (algo); + if (mdlen < 1 || mdlen > 64) + { + return; + } + + if (expectlen == 0) + expectlen = mdlen; + + if (expectlen != mdlen) + { + fail ("check_one_md_final: algo %d, digest length mismatch\n", algo); + return; + } + + for (i = 0; i < sizeof(inbuf); i++) + inbuf[i] = i; + + gcry_md_hash_buffer (algo, xorbuf, NULL, 0); + for (i = 1; i < sizeof(inbuf); i++) + { + gcry_md_hash_buffer (algo, digest, inbuf, i); + for (j = 0; j < expectlen; j++) + xorbuf[j] ^= digest[j]; + } + + if (memcmp(expect, xorbuf, expectlen) != 0) + { + printf ("computed: "); + for (i = 0; i < expectlen; i++) + printf ("%02x ", xorbuf[i] & 0xFF); + printf ("\nexpected: "); + for (i = 0; i < expectlen; i++) + printf ("%02x ", expect[i] & 0xFF); + printf ("\n"); + + fail ("check_one_md_final: algo %d, digest mismatch\n", algo); + } +} + + +static void check_digests (void) { static const char blake2_data_vector[] = @@ -9734,6 +9784,142 @@ check_digests (void) "ral Public License for more details.", "\x8b\x91\x3f\x0e\x85\xae\x43\x25\x6d\x28\x38\x6c\x09\x5c\xc7\x72" "\xcc\x2e\x78\x89\x7e\x2e\x4e\x5a\x3d\xf6\x55\xfe\x87\xbe\xa6\xbc" }, + + { GCRY_MD_GOSTR3411_CP, + "*", + "\x72\xd7\xe3\xbf\xa0\x08\xc9\x62\xae\xa9\xc5\xd8\x93\x5f\x17\xd7" + "\x3f\xf2\x52\xb4\xc1\x16\xcf\x63\xa4\xcc\x4a\x8c\x7f\xe5\x60\x2c" }, + { GCRY_MD_MD4, + "*", + "\xe8\xb9\xe4\x59\x61\x08\xc0\xfe\x54\xef\xc5\x8e\x20\x7c\x9b\x37" }, + { GCRY_MD_MD5, + "*", + "\x0b\x1e\xab\xa2\x5e\x48\x76\x92\xae\x16\x12\xde\x5f\xb3\x29\x41" }, + { GCRY_MD_RMD160, + "*", + "\x28\xfd\xd6\xa8\x95\x29\x43\x6b\x5e\xd9\xa0\x06\x82\xbb\xe6\x10" + "\xd3\xcc\x79\x33" }, + { GCRY_MD_SHA1, + "*", + "\xd8\x37\x46\x1a\x46\xfe\x42\x11\x7d\x50\xca\xf7\x3d\x7e\x0c\x36" + "\x42\x0c\x15\xb6" }, + { GCRY_MD_SHA224, + "*", + "\x2e\xba\x51\x6c\x71\x5a\x1d\xb8\x6b\x57\xfb\xf1\x46\xa0\xa7\x1d" + "\x72\x66\xaf\x90\xb8\x01\x18\xc8\x58\x57\xa5\x63" }, + { GCRY_MD_SHA256, + "*", + "\x30\xed\xe4\x69\xf3\x1c\x70\x8a\x6d\x92\x00\xac\xd8\x08\x89\xea" + "\x7e\x92\xff\x02\x0b\x72\x4a\xdf\xa9\x2b\x9f\x80\xba\xd0\x25\xd0" }, + { GCRY_MD_SHA384, + "*", + "\x21\xd7\x40\xdf\x34\x13\xcf\x56\xf7\x61\x0a\x1b\x11\xb7\x1e\x01" + "\x87\xad\xbb\x3e\x9a\xe8\xaa\xaa\xbc\x3a\x89\x39\x0a\xa9\xcb\x4f" + "\x09\x75\x4c\x44\x59\x42\xf5\x13\x5f\xe5\xa6\x2b\x16\xbe\xfc\xdf" }, + { GCRY_MD_SHA512, + "*", + "\x5c\xbe\x01\x03\xbd\x8d\xa1\x38\x5e\x87\x00\x94\x8d\x14\xd0\xb3" + "\x2c\x88\xeb\xb8\xf6\xcc\x06\x44\x54\xb1\x58\x88\xa9\x67\xa0\xe3" + "\x0d\x28\x8b\xf4\x2c\xc6\x7a\xdc\x1a\x35\xbf\x0c\xc8\x35\xf0\x24" + "\x69\xb5\xfe\x15\x6f\x71\xbd\x87\x07\x52\x27\xcc\xdc\x21\x84\x21" }, + { GCRY_MD_SHA3_224, + "*", + "\x1a\xa6\x6f\x1a\x3c\x62\x14\x75\xea\x9d\x49\x4d\x39\x01\x2b\xbd" + "\x4d\xe1\x58\xbc\x32\xac\x48\xcf\x6a\x1a\x54\x34" }, + { GCRY_MD_SHA3_256, + "*", + "\x87\xf8\x0e\x78\xc1\x7b\x0c\x36\x4c\xbb\x8d\xca\x5e\x77\xc3\xfd" + "\x95\xbd\xaf\x94\x85\xc6\x0c\xe6\x22\x52\xeb\x22\x50\x32\x48\x57" }, + { GCRY_MD_SHA3_384, + "*", + "\x89\x5a\xd6\xc8\x60\x20\x66\xe7\x9e\xb3\x6d\x5c\x07\xd7\x5e\xd0" + "\x48\x84\x9d\x51\x75\x14\x77\xdb\xcd\xbf\x70\x18\xdc\x64\x53\x85" + "\x94\x95\xa5\xd3\x26\x9c\xf1\x63\x14\x8d\x11\xa0\xfc\xd8\x05\x9e" }, + { GCRY_MD_SHA3_512, + "*", + "\x53\x0b\x1c\xb7\xff\x2c\xaa\x7e\x62\x15\xa7\x57\x9a\xd0\xcf\x4f" + "\xa5\xae\xe0\x05\x1c\x77\x0f\x29\x5b\x3f\xba\xab\x88\x0c\x0b\x8e" + "\x10\xcf\x3d\xa9\x0d\x1e\x97\x98\x96\xeb\x24\x2e\x70\x30\xd0\x78" + "\x2b\x9e\x30\xad\x5d\xcf\x56\xcf\xd0\xc1\x58\x95\x53\x09\x78\xd6" }, + { GCRY_MD_SM3, + "*", + "\xb6\xfc\x1e\xc4\xad\x9b\x88\xbd\x08\xaa\xf3\xb3\xfa\x4f\x1b\x9c" + "\xd6\x9a\x32\x09\x28\x9e\xda\x3a\x99\xb6\x09\x8f\x35\x99\xa6\x11" }, + { GCRY_MD_STRIBOG256, + "*", + "\x35\x0b\xec\x46\x1f\x98\x19\xe7\x33\x12\xda\x9f\xaf\x3d\x32\xa6" + "\xe4\xa5\x80\x38\x1b\x56\x68\x13\x2d\x0d\xa6\xfd\xfa\xe5\x3d\xf2" }, + { GCRY_MD_STRIBOG512, + "*", + "\x01\x4c\xbd\xd4\x3a\x1a\x51\x9e\xa8\x7c\x1f\xd2\xc3\x2e\x71\x78" + "\x03\x46\xd0\x1b\x30\xdd\x07\xf6\x82\x2b\xa4\x43\x8f\x95\x44\x9d" + "\x92\x3a\x17\x70\x1b\xdd\xfc\x8f\x71\x20\xc6\xa0\xd8\x6f\xb2\x06" + "\xb6\x61\x27\x48\x45\x94\x96\xe7\xdc\xf5\x7a\x2f\x83\x82\x03\x08" }, + { GCRY_MD_TIGER1, + "*", + "\x95\xe1\x25\x8f\xc5\x4b\x82\x12\x69\x83\xfa\xfd\x79\x7d\x87\x38" + "\x01\x4f\xf9\x24\xa2\xf0\x8f\x85" }, + { GCRY_MD_WHIRLPOOL, + "*", + "\x8e\x02\x8e\x8d\xeb\x03\xcc\x37\xf2\x67\x61\x4e\x16\x27\x06\x13" + "\x26\x8c\x35\x17\x0c\xab\x3c\x8b\x25\xc3\x3a\x2b\x7d\x54\xbf\xcf" + "\x7e\xa2\xe4\x4f\x8d\x67\xb7\x85\xfa\x54\x76\x7c\xb0\x24\x87\xd5" + "\x0e\x7d\x3b\x02\x8f\x30\x9e\x91\x78\xea\xc6\xdc\x0e\xee\x71\xca" }, + { GCRY_MD_CRC24_RFC2440, + "*", + "\x44\x53\xd8" }, + { GCRY_MD_CRC32, + "*", + "\x96\x11\x46\x4d" }, + { GCRY_MD_TIGER, + "*", + "\x12\x82\x4b\xc5\x8f\x25\xe1\x95\x38\x87\x7d\x79\xfd\xfa\x83\x69" + "\x85\x8f\xf0\xa2\x24\xf9\x4f\x01" }, + { GCRY_MD_TIGER2, + "*", + "\xc6\x8f\x98\x71\xee\xb3\x1a\xf6\x77\x50\x8e\x74\x98\x08\x6c\x42" + "\xc0\x37\x43\xc2\x17\x89\x5f\x98" }, + { GCRY_MD_CRC32_RFC1510, + "*", + "\xf4\x45\xfd\x43" }, + { GCRY_MD_BLAKE2B_512, + "*", + "\xe0\xf7\x38\x87\x07\xf9\xfd\xeb\x58\x8d\xb9\xb8\xa4\x85\x21\x8e" + "\x56\xa9\xe6\x8d\x64\x4d\xfb\xe8\x8a\x84\xa4\x45\xc7\x80\x4b\x1f" + "\x63\x0b\x27\x84\x96\xd4\xeb\x99\x19\xcb\xc6\x37\x01\x42\xb9\x03" + "\x50\x63\xdf\xb9\x5e\xc5\xb1\xda\x2d\x19\xeb\x65\x73\xd2\xfa\xfa" }, + { GCRY_MD_BLAKE2B_384, + "*", + "\x44\xde\xb8\x2b\x46\x22\xe5\xc6\xa5\x66\x8a\x88\x2b\xc3\x2c\x27" + "\xc1\x4e\x4f\x6b\x70\x96\xcb\x1a\x99\x04\x67\x54\x8a\x0a\x55\xb4" + "\xdb\x8b\xf6\x36\xfc\x2e\xf6\x2a\x6b\xe2\x1d\x09\x0e\x2f\x65\x33" }, + { GCRY_MD_BLAKE2B_256, + "*", + "\x75\xd1\x62\xad\x02\xf1\x3f\xa3\x95\x2f\x5f\x89\x13\x2c\xf4\x2f" + "\xc3\x84\xd2\x46\xbc\x35\x2b\x13\x01\xe0\x9e\x46\x55\x92\x40\x5a" }, + { GCRY_MD_BLAKE2B_160, + "*", + "\x8c\x67\x38\x0e\xf8\xc7\xb6\x3e\x7f\x8e\x32\x73\x8a\xba\xa4\x71" + "\x87\x9a\xb0\x4c" }, + { GCRY_MD_BLAKE2S_256, + "*", + "\x71\x4a\x6d\xe4\xbb\x6c\x9f\x22\xff\x50\x02\xba\x5f\x54\xa6\x39" + "\x9d\x07\x95\x82\x38\x98\xac\x62\xab\xc6\x13\x12\x65\x64\x9e\x69" }, + { GCRY_MD_BLAKE2S_224, + "*", + "\x4c\x01\xe6\x67\xa2\x02\xd1\x62\x9b\xc3\x3b\xb5\x93\xc4\x3c\xa9" + "\x90\x7b\x96\x70\xfd\xdf\xd1\xc3\xad\x09\xa9\xe7" }, + { GCRY_MD_BLAKE2S_160, + "*", + "\x21\xca\x18\x74\x76\x3c\x6b\xe4\x92\x01\xd6\xd5\x91\xd1\x53\xfb" + "\x37\x73\x99\xb9" }, + { GCRY_MD_BLAKE2S_128, + "*", + "\x1d\x87\xfa\x69\xe0\x93\xd9\xcd\xb0\x3c\x52\x00\x35\xe1\xa3\xee" }, + { GCRY_MD_GOSTR3411_94, + "*", + "\x6e\xa9\x9e\x23\xde\x5f\x7a\xb7\x7f\xa7\xdc\xe1\xc8\x05\x46\xae" + "\x1e\x7c\x76\xbb\x52\x0f\x52\x07\x78\x59\xd3\xc1\x64\xdb\x51\xac" }, { 0 } }; gcry_error_t err; @@ -9756,6 +9942,19 @@ check_digests (void) algos[i].md); continue; } + + if (!strcmp (algos[i].data, "*")) + { + if (verbose) + fprintf (stderr, " checking %s [%i] for final handling\n", + gcry_md_algo_name (algos[i].md), + algos[i].md); + + check_one_md_final (algos[i].md, algos[i].expect, algos[i].expectlen); + + continue; + } + if (verbose) fprintf (stderr, " checking %s [%i] for length %d\n", gcry_md_algo_name (algos[i].md), |