[PATCH] stribog: add carry bug emulation

Jussi Kivilinna jussi.kivilinna at iki.fi
Thu May 30 19:18:12 CEST 2019


* cipher/stribog.c (STRIBOG_CONTEXT): Add 'use_carry_bugemu'.
(stribog_init_512): Set 'use_carry_bugemu' if GCRY_MD_FLAG_BUGEMU1 flag
is set.
(transform_bits): Add 'use_carry_bugemu' path.
* tests/basic.c (check_one_md): Add 'flags' parameter.
(check_digests): Add Stribug bog emulation check.
--

Signed-off-by: Jussi Kivilinna <jussi.kivilinna at iki.fi>
---
 cipher/stribog.c |   29 +++++++++++++++++++++++------
 tests/basic.c    |   36 +++++++++++++++++++++++++++++-------
 2 files changed, 52 insertions(+), 13 deletions(-)

diff --git a/cipher/stribog.c b/cipher/stribog.c
index 267872474..9d45047d8 100644
--- a/cipher/stribog.c
+++ b/cipher/stribog.c
@@ -39,6 +39,7 @@ typedef struct
   };
   u64 N[8];
   u64 Sigma[8];
+  int use_carry_bugemu;
 } STRIBOG_CONTEXT;
 
 
@@ -1208,6 +1209,9 @@ stribog_init_512 (void *context, unsigned int flags)
 
   hd->bctx.blocksize = 64;
   hd->bctx.bwrite = transform;
+
+  if ((flags & GCRY_MD_FLAG_BUGEMU1))
+    hd->use_carry_bugemu = 1;
 }
 
 static void
@@ -1242,13 +1246,26 @@ transform_bits (STRIBOG_CONTEXT *hd, const unsigned char *data, unsigned count)
         }
     }
 
-  hd->Sigma[0] += M[0];
-  cf = 0;
-  for (i = 1; i < 8; i++)
+  if (hd->use_carry_bugemu)
     {
-      if (hd->Sigma[i-1] != M[i-1])
-	cf = (hd->Sigma[i-1] < M[i-1]);
-      hd->Sigma[i] += M[i] + cf;
+      /* Bug compatibility Stribog version. */
+      hd->Sigma[0] += M[0];
+      for (i = 1; i < 8; i++)
+	if (hd->Sigma[i-1] < M[i-1])
+	  hd->Sigma[i] += M[i] + 1;
+	else
+	  hd->Sigma[i] += M[i];
+    }
+  else
+    {
+      hd->Sigma[0] += M[0];
+      cf = 0;
+      for (i = 1; i < 8; i++)
+	{
+	  if (hd->Sigma[i-1] != M[i-1])
+	    cf = (hd->Sigma[i-1] < M[i-1]);
+	  hd->Sigma[i] += M[i] + cf;
+	}
     }
 }
 
diff --git a/tests/basic.c b/tests/basic.c
index 0ce88e291..3273c9e7a 100644
--- a/tests/basic.c
+++ b/tests/basic.c
@@ -8193,8 +8193,8 @@ fillbuf_count (char *buf, size_t buflen, unsigned char pos)
 
 
 static void
-check_one_md (int algo, const char *data, int len, const char *expect, int elen,
-	      const char *key, int klen)
+check_one_md (int algo, int flags, const char *data, int len,
+	      const char *expect, int elen, const char *key, int klen)
 {
   gcry_md_hd_t hd, hd2;
   unsigned char *p;
@@ -8203,7 +8203,7 @@ check_one_md (int algo, const char *data, int len, const char *expect, int elen,
   int xof = 0;
   gcry_error_t err = 0;
 
-  err = gcry_md_open (&hd, algo, 0);
+  err = gcry_md_open (&hd, algo, flags);
   if (err)
     {
       fail ("algo %d, gcry_md_open failed: %s\n", algo, gpg_strerror (err));
@@ -8244,7 +8244,7 @@ check_one_md (int algo, const char *data, int len, const char *expect, int elen,
       /* Test hashing small input sizes first as full block, then byte-by-byte
        * and check that resulting digests are the same. */
 
-      err = gcry_md_open (&hd2, algo, 0);
+      err = gcry_md_open (&hd2, algo, flags);
       if (err)
 	{
 	  gcry_md_close (hd);
@@ -8438,7 +8438,7 @@ check_one_md (int algo, const char *data, int len, const char *expect, int elen,
 
 	  crclen = gcry_md_get_algo_dlen (crcalgo);
 
-	  err = gcry_md_open (&crc1, crcalgo, 0);
+	  err = gcry_md_open (&crc1, crcalgo, flags);
 	  if (err)
 	    {
 	      fail ("algo %d, crcalgo: %d, gcry_md_open failed: %s\n", algo,
@@ -8446,7 +8446,7 @@ check_one_md (int algo, const char *data, int len, const char *expect, int elen,
 	      return;
 	    }
 
-	  err = gcry_md_open (&crc2, crcalgo, 0);
+	  err = gcry_md_open (&crc2, crcalgo, flags);
 	  if (err)
 	    {
 	      fail ("algo %d, crcalgo: %d, gcry_md_open failed: %s\n", algo,
@@ -9964,7 +9964,7 @@ check_digests (void)
                  (!strcmp (algos[i].data, "!") || !strcmp (algos[i].data, "?"))?
                  1000000 : (int)strlen(algos[i].data));
 
-      check_one_md (algos[i].md, algos[i].data,
+      check_one_md (algos[i].md, 0, algos[i].data,
 		    algos[i].datalen > 0 ? algos[i].datalen
 					 : strlen (algos[i].data),
 		    algos[i].expect, algos[i].expectlen,
@@ -10030,6 +10030,28 @@ check_digests (void)
       gcry_md_close (hd);
     }
 
+  /* Check the Stribog bug emulation.  */
+  if (!gcry_md_test_algo (GCRY_MD_STRIBOG512) && !in_fips_mode)
+    {
+      const char *data =
+	"\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff"
+	"\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff"
+	"\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff"
+	"\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff"
+	"\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff"
+	"\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff"
+	"\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff"
+	"\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff";
+      const char *expect =
+	"\xc5\xe8\xac\x15\x6e\x3c\xd7\xf3\x95\xfa\x9c\x8b\xf8\xfb\x39\x95"
+	"\xdc\xfa\xdc\x0e\xe5\x39\xd5\x6e\x51\x38\x80\x4b\x48\x8e\x17\xb8"
+	"\x46\xfc\x7b\xcc\xf8\x83\xb2\x19\x14\xac\xfd\x0a\xdd\x48\xe5\x5a"
+	"\xc3\x59\xa7\x56\x4f\x39\x61\x9c\xd6\xad\x9d\x93\xa3\x5b\xf9\xa9";
+
+      check_one_md (GCRY_MD_STRIBOG512, GCRY_MD_FLAG_BUGEMU1, data,
+		    strlen (data), expect, 0, NULL, 0);
+    }
+
  leave:
   if (verbose)
     fprintf (stderr, "Completed hash checks.\n");




More information about the Gcrypt-devel mailing list