[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