c++libcryptosha-3

Incorrect behaviour generating SHA3 hash with cryptopp


I'm seeing a very odd difference in behaviour in generating SHA3 hashes with cryptopp on RHEL7 vs Debian9. If I use a SHA1 or MD5 hash instead the output is identical on both platforms. I've reduced it down to the following minimal progrma:

#include <iostream>
#include <cryptopp/sha3.h>
#include <cryptopp/filters.h>
#include <cryptopp/hex.h>

using namespace CryptoPP;

int main(int argc, const char* argv[])
{
   {
      CryptoPP::SHA3_256 sha256;
      std::string hash = "";
      StringSource("", true, new HashFilter(sha256, new HexEncoder(new StringSink(hash))));
      std::cout << "hash='" << hash << "'\n";
   }
   {
      CryptoPP::SHA3_256 sha256;
      std::string hash = "";
      StringSource("{}", true, new HashFilter(sha256, new HexEncoder(new StringSink(hash))));
      std::cout << "hash='" << hash << "'\n";
   }
}

On Debian the output is:

hash='A7FFC6F8BF1ED76651C14756A061D662F580FF4DE43B49FA82D80A4B80F8434A'
hash='840EB7AA2A9935DE63366BACBE9D97E978A859E93DC792A0334DE60ED52F8E99'

which is correct according to the online converter at https://emn178.github.io/online-tools/sha3_256.html

But on RHEL7 the output is bizarrely:

hash='C5D2460186F7233C927E7DB2DCC703C0E500B653CA82273B7BFAD8045D85A470'
hash='B48D38F93EAA084033FC5970BF96E559C33C4CDC07D889AB00B4D63F9590739D'

So either I'm doing something wrong or there is a bug in the library or a misinstallation.

Am I misusing libcrytopp? Something like a missing MessageEnd()?

On RHEL7:

>ldd ./hashtest 
    linux-vdso.so.1 =>  (0x00007ffecd1b1000)
    libcryptopp.so.6 => /lib64/libcryptopp.so.6 (0x00007f71c3707000)
    libstdc++.so.6 => /lib64/libstdc++.so.6 (0x00007f71c3400000)
    libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x00007f71c31ea000)
    libc.so.6 => /lib64/libc.so.6 (0x00007f71c2e1d000)
    libpthread.so.0 => /lib64/libpthread.so.0 (0x00007f71c2c01000)
    libm.so.6 => /lib64/libm.so.6 (0x00007f71c28ff000)
    /lib64/ld-linux-x86-64.so.2 (0x00007f71c3e2e000)
>file /lib64/libcryptopp.so.6.0.0 
/lib64/libcryptopp.so.6.0.0: ELF 64-bit LSB shared object, x86-64, version 1 (GNU/Linux), dynamically linked, BuildID[sha1]=4a0941023c6e957077cb555536a509a0ef93bf04, stripped

On Debian:

>ldd ./hashtest 
    linux-vdso.so.1 (0x00007ffedc5e6000)
    libcrypto++.so.6 => /usr/lib/x86_64-linux-gnu/libcrypto++.so.6 (0x00007f1d3b79a000)
    libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007f1d3b418000)
    libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007f1d3b201000)
    libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f1d3ae62000)
    libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f1d3ac45000)
    libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f1d3a941000)
    /lib64/ld-linux-x86-64.so.2 (0x00007f1d3bf35000)
>file /usr/lib/x86_64-linux-gnu/libcrypto++.so.6.0.0 
/usr/lib/x86_64-linux-gnu/libcrypto++.so.6.0.0: ELF 64-bit LSB shared object, x86-64, version 1 (GNU/Linux), dynamically linked, BuildID[sha1]=5c6cb06479005d2ebfa40c75e5489c915d314b70, stripped

It seems to be v6.0.0 on both platforms but:

>apt-cache show crypto++
[snip]
Package: libcrypto++-dev
Source: libcrypto++
Version: 5.6.4-7

>yum info --enablerepo=epel cryptopp
Installed Packages
Name        : cryptopp
Arch        : x86_64
Version     : 5.6.2
Release     : 10.el7
Size        : 5.2 M
Repo        : installed
From repo   : epel
Summary     : C++ class library of cryptographic schemes
URL         : http://www.cryptopp.com/
Licence     : Boost
Description : Crypto++ Library is a free C++ class library of cryptographic schemes.
            : See http://www.cryptopp.com/ for a list of supported algorithms.
            : 
            : One purpose of Crypto++ is to act as a repository of public domain
            : (not copyrighted) source code. Although the library is copyrighted as a
            : compilation, the individual files in it are in the public domain.

Solution

  • You need to get your RHEL box to at least cryptopp version 5.6.4, because that's where the "real" SHA3 implementation came in. Prior to 5.6.4 the implementation was using the original padding scheme specified by the "Keccak" proposal that was selected as the basis of SHA3, not the modified padding scheme that was defined in the ratified SHA3 standard.

    See https://github.com/weidai11/cryptopp/issues/158 for background, and the release comments at the bottom of https://github.com/weidai11/cryptopp for notification of the change in 5.6.4.