Repository: randombit/botan (cpp)

Issue:
Streebog incorrect output
```
operation name: Digest
digest: STREEBOG-256
cleartext: {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
 0x77, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
 0x0f, 0x00, 0x00, 0x00, 0xc3, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x2d, 0xff, 0xf2, 0xff, 
 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x23, 0xff, 0x27, 0xfe, 0xff, 0xff, 0xff, 0x00, 0x2c} (64 bytes)

Module Veracrypt result:

{0x68, 0xe8, 0xd7, 0x7a, 0x02, 0xaa, 0xc4, 0xa8, 0x44, 0xa1, 0xd8, 0xe4, 0x6b, 0x27, 0xf3, 0x5b, 
 0xb9, 0x29, 0x3e, 0x3d, 0xc5, 0x84, 0xdc, 0x0e, 0x42, 0xa7, 0xe1, 0xb0, 0x79, 0x94, 0x53, 0x80} (32 bytes)

Module libgcrypt result:

{0x68, 0xe8, 0xd7, 0x7a, 0x02, 0xaa, 0xc4, 0xa8, 0x44, 0xa1, 0xd8, 0xe4, 0x6b, 0x27, 0xf3, 0x5b, 
 0xb9, 0x29, 0x3e, 0x3d, 0xc5, 0x84, 0xdc, 0x0e, 0x42, 0xa7, 0xe1, 0xb0, 0x79, 0x94, 0x53, 0x80} (32 bytes)

Module Botan result:

{0xfa, 0x07, 0xff, 0x3e, 0xfd, 0x87, 0xd4, 0xd0, 0x53, 0xd4, 0x16, 0x81, 0x3c, 0xbb, 0xd4, 0x8d, 
 0x87, 0x8b, 0xbd, 0xbf, 0x55, 0x8d, 0xcc, 0xf3, 0xfc, 0x8e, 0xa5, 0x60, 0x2f, 0xf0, 0x7b, 0x5d} (32 bytes)
```

Though not included in this log, LibreSSL produces the same output as Veracrypt and libgcrypt.
Both libgcrypt and LibreSSL had issues with Streebog in the past:

https://cvsweb.openbsd.org/cgi-bin/cvsweb/src/lib/libcrypto/gost/streebog.c?rev=1.6&content-type=text/x-cvsweb-markup

https://github.com/gpg/libgcrypt/commit/da6cd4fea30f79cf9d8f9b2f1c6daf3aea39fa9c

Pull request:
Fix a carry handling bug in Streebog
Closes #2082

Patch:
diff --git a/src/lib/hash/streebog/streebog.cpp b/src/lib/hash/streebog/streebog.cpp
index c92e1123f..0e2a43b78 100644
--- a/src/lib/hash/streebog/streebog.cpp
+++ b/src/lib/hash/streebog/streebog.cpp
@@ -194,10 +194,11 @@ void Streebog::compress_64(const uint64_t M[], bool last_block)
          {
          const uint64_t m = force_le(M[i]);
          const uint64_t hi = force_le(m_S[i]);
-         const uint64_t t = hi + m;
+         const uint64_t t = hi + m + carry;
 
-         m_S[i] = force_le(t + carry);
-         carry = (t < hi ? 1 : 0) | (t < m ? 1 : 0);
+         m_S[i] = force_le(t);
+         if(t != m)
+            carry = (t < m);
          }
       }
    }


Test patch:
diff --git a/src/tests/data/hash/streebog.vec b/src/tests/data/hash/streebog.vec
index 8e5037558..2d9d258a9 100644
--- a/src/tests/data/hash/streebog.vec
+++ b/src/tests/data/hash/streebog.vec
@@ -396,6 +396,10 @@ Out = 1ef768f7ae820c2966b7c60b0cf208ab89c1f7b60f9b2cab61253c38d1f2c987
 In = 290f597702e009d86f49d5362346309e26919eacbcb86165be4906056d43f95a1e181b2b0c12785c929f17a3d25943f5313641c915bf5dd38882d587da1da65d6658f89764e28ee13a24ac9349e6803579baa17d6ca571793c13f7a0fe46043deeed08922fb2e2353d8718c5f1c7f1fba2df54e9cbbad54a750da656863d2843
 Out = c9c82e740ccc34fc0c14c61ab4eb037542d77ffda00d484aff97c1144346704f
 
+# https://github.com/randombit/botan/issues/2082
+In = ffffffffffffffffffffffffffffffff7700000000000000ffffffffffffffff0f000000c3000000ffffffff2dfff2ffffffffffffffff23ff27feffffff002c
+Out = 68e8d77a02aac4a844a1d8e46b27f35bb9293e3dc584dc0e42a7e1b079945380
+
 [Streebog-512]
 # From https://tools.ietf.org/html/rfc6986
 In = 303132333435363738393031323334353637383930313233343536373839303132333435363738393031323334353637383930313233343536373839303132
@@ -794,3 +798,11 @@ Out = a7bcd688131c97b57dedc7aebd845e0042ea9f8d3a425f11f57ddfef8eaec040e93d9219b6
 In = 25894e39aef06148d682f48a34f100ea694e446bbf79caa7806c7c6f3f8a60a94b9c8b2877c617fead17ac576d8dafd3f8514e49825d54dc9a8916330dc560204bd795d0ce00a49ba3c25c7921381c057bc6a1abb362db79497c878321c2a71793f2bfb7ad211700fecd486241cc6197a50075560147b20b9cbe2f992f516c61
 Out = b4ce87a416b83be3417ccbd7000d658acce2a5c3b57c92aa8ca3d912f20580748c2534a157b4ead16059499b9b11ae8ff07cca94a2a5a314b4ac4faaddcb0162
 
+# https://github.com/randombit/botan/issues/2082
+# https://github.com/gpg/libgcrypt/commit/da6cd4fea30f79cf9d8f9b2f1c6daf3aea39fa9c
+
+In = EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE16111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111116
+Out = 8b06f41e59907d9636e892caf5942fcdfb71fa31169a5e70f0edb873664df41c2cce6e06dc6755d15a61cdeb92bd607cc4aaca6732bf3568a23a210dd520fd41
+
+In = ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+Out = 90a161d12ad309498d3fe5d48202d8a4e9c406d6a264aeab258ac5ecc37a7962aaf9587a5abb09b6bb81ec4b3752a3ff5a838ef175be5772056bc5fe54fcfc7e
\ No newline at end of file