Fix message digest final function for MD4, MD5 and RMD160
authorJussi Kivilinna <jussi.kivilinna@iki.fi>
Thu, 9 May 2019 18:43:52 +0000 (21:43 +0300)
committerJussi Kivilinna <jussi.kivilinna@iki.fi>
Thu, 9 May 2019 18:43:52 +0000 (21:43 +0300)
* 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>
cipher/md4.c
cipher/md5.c
cipher/rmd160.c
tests/basic.c

index f625889..b75bc5e 100644 (file)
@@ -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);
     }
 
index 67511ba..94fcdf0 100644 (file)
@@ -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);
     }
 
index f15eec2..24210a0 100644 (file)
@@ -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);
     }
 
index 55a8b72..31595d0 100644 (file)
@@ -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),