summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--CMakeLists.txt20
-rw-r--r--CTestCustom.cmake.in2
-rw-r--r--Source/.gitattributes3
-rw-r--r--Source/CMakeLists.txt3
-rw-r--r--Source/CPack/WiX/cmCPackWIXGenerator.cxx4
-rw-r--r--Source/CTest/cmCTestLaunch.cxx15
-rw-r--r--Source/Modules/FindLibRHash.cmake73
-rw-r--r--Source/cmCryptoHash.cxx97
-rw-r--r--Source/cmCryptoHash.h61
-rw-r--r--Source/cmFileCommand.cxx3
-rw-r--r--Source/cmFilePathUuid.cxx4
-rw-r--r--Source/cmGlobalGenerator.cxx13
-rw-r--r--Source/cmLocalGenerator.cxx16
-rw-r--r--Source/cmSystemTools.cxx6
-rw-r--r--Source/cmUuid.cxx31
-rw-r--r--Source/cm_sha2.c1613
-rw-r--r--Source/cm_sha2.h140
-rw-r--r--Source/cm_sha2_mangle.h42
-rw-r--r--Tests/CMakeLists.txt4
-rw-r--r--Tests/FindLibRHash/CMakeLists.txt10
-rw-r--r--Tests/FindLibRHash/Test/CMakeLists.txt17
-rw-r--r--Tests/FindLibRHash/Test/main.c7
-rwxr-xr-xUtilities/Scripts/clang-format.bash2
-rwxr-xr-xUtilities/Scripts/update-librhash.bash43
-rw-r--r--Utilities/cmThirdParty.h.in1
-rw-r--r--Utilities/cm_rhash.h14
-rw-r--r--Utilities/cmlibrhash/.gitattributes1
-rw-r--r--Utilities/cmlibrhash/CMakeLists.txt38
-rw-r--r--Utilities/cmlibrhash/COPYING15
-rw-r--r--Utilities/cmlibrhash/README7
-rw-r--r--Utilities/cmlibrhash/librhash/algorithms.c220
-rw-r--r--Utilities/cmlibrhash/librhash/algorithms.h120
-rw-r--r--Utilities/cmlibrhash/librhash/byte_order.c150
-rw-r--r--Utilities/cmlibrhash/librhash/byte_order.h156
-rw-r--r--Utilities/cmlibrhash/librhash/hex.c188
-rw-r--r--Utilities/cmlibrhash/librhash/hex.h25
-rw-r--r--Utilities/cmlibrhash/librhash/md5.c236
-rw-r--r--Utilities/cmlibrhash/librhash/md5.h31
-rw-r--r--Utilities/cmlibrhash/librhash/rhash.c872
-rw-r--r--Utilities/cmlibrhash/librhash/rhash.h280
-rw-r--r--Utilities/cmlibrhash/librhash/sha1.c196
-rw-r--r--Utilities/cmlibrhash/librhash/sha1.h31
-rw-r--r--Utilities/cmlibrhash/librhash/sha256.c241
-rw-r--r--Utilities/cmlibrhash/librhash/sha256.h32
-rw-r--r--Utilities/cmlibrhash/librhash/sha512.c255
-rw-r--r--Utilities/cmlibrhash/librhash/sha512.h32
-rw-r--r--Utilities/cmlibrhash/librhash/ustd.h39
-rw-r--r--Utilities/cmlibrhash/librhash/util.h31
-rwxr-xr-xbootstrap6
49 files changed, 3496 insertions, 1950 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index a5702e1..7aa8010 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -104,7 +104,7 @@ macro(CMAKE_HANDLE_SYSTEM_LIBRARIES)
# Allow the user to enable/disable all system utility library options by
# defining CMAKE_USE_SYSTEM_LIBRARIES or CMAKE_USE_SYSTEM_LIBRARY_${util}.
- set(UTILITIES BZIP2 CURL EXPAT FORM JSONCPP LIBARCHIVE LIBLZMA LIBUV ZLIB)
+ set(UTILITIES BZIP2 CURL EXPAT FORM JSONCPP LIBARCHIVE LIBLZMA LIBRHASH LIBUV ZLIB)
foreach(util ${UTILITIES})
if(NOT DEFINED CMAKE_USE_SYSTEM_LIBRARY_${util}
AND DEFINED CMAKE_USE_SYSTEM_LIBRARIES)
@@ -144,6 +144,7 @@ macro(CMAKE_HANDLE_SYSTEM_LIBRARIES)
"${CMAKE_USE_SYSTEM_LIBRARY_LIBLZMA}" "NOT CMAKE_USE_SYSTEM_LIBARCHIVE" ON)
option(CMAKE_USE_SYSTEM_FORM "Use system-installed libform" "${CMAKE_USE_SYSTEM_LIBRARY_FORM}")
option(CMAKE_USE_SYSTEM_JSONCPP "Use system-installed jsoncpp" "${CMAKE_USE_SYSTEM_LIBRARY_JSONCPP}")
+ option(CMAKE_USE_SYSTEM_LIBRHASH "Use system-installed librhash" "${CMAKE_USE_SYSTEM_LIBRARY_LIBRHASH}")
option(CMAKE_USE_SYSTEM_LIBUV "Use system-installed libuv" "${CMAKE_USE_SYSTEM_LIBRARY_LIBUV}")
# For now use system KWIML only if explicitly requested rather
@@ -298,6 +299,23 @@ macro (CMAKE_BUILD_UTILITIES)
add_subdirectory(Utilities/KWIML)
endif()
+ if(CMAKE_USE_SYSTEM_LIBRHASH)
+ if(NOT CMAKE_VERSION VERSION_LESS 3.0)
+ find_package(LibRHash)
+ else()
+ message(FATAL_ERROR "CMAKE_USE_SYSTEM_LIBRHASH requires CMake >= 3.0")
+ endif()
+ if(NOT LibRHash_FOUND)
+ message(FATAL_ERROR
+ "CMAKE_USE_SYSTEM_LIBRHASH is ON but LibRHash is not found!")
+ endif()
+ set(CMAKE_LIBRHASH_LIBRARIES LibRHash::LibRHash)
+ else()
+ set(CMAKE_LIBRHASH_LIBRARIES cmlibrhash)
+ add_subdirectory(Utilities/cmlibrhash)
+ CMAKE_SET_TARGET_FOLDER(cmlibrhash "Utilities/3rdParty")
+ endif()
+
#---------------------------------------------------------------------
# Build zlib library for Curl, CMake, and CTest.
set(CMAKE_ZLIB_HEADER "cm_zlib.h")
diff --git a/CTestCustom.cmake.in b/CTestCustom.cmake.in
index 48dd3de..07a9fdb 100644
--- a/CTestCustom.cmake.in
+++ b/CTestCustom.cmake.in
@@ -17,7 +17,6 @@ list(APPEND CTEST_CUSTOM_WARNING_EXCEPTION
"Utilities.cmbzip2."
"Source.CTest.Curl"
"Source.CursesDialog.form"
- "Source.cm_sha2.*warning.*cast increases required alignment of target type"
"Utilities.cmcurl"
"Utilities.cmexpat."
"Utilities.cmlibarchive"
@@ -84,7 +83,6 @@ list(APPEND CTEST_CUSTOM_WARNING_EXCEPTION
"warning: Value stored to 'yytoken' is never read"
"index_encoder.c.241.2. warning: Value stored to .out_start. is never read"
"index.c.*warning: Access to field.*results in a dereference of a null pointer.*loaded from variable.*"
- "cm_sha2.*warning: Value stored to.*is never read"
"cmFortranLexer.cxx:[0-9]+:[0-9]+: warning: Call to 'realloc' has an allocation size of 0 bytes"
"testProcess.*warning: Dereference of null pointer .loaded from variable .invalidAddress.."
"liblzma/simple/x86.c:[0-9]+:[0-9]+: warning: The result of the '<<' expression is undefined"
diff --git a/Source/.gitattributes b/Source/.gitattributes
index 5002b2a..e9e35bd 100644
--- a/Source/.gitattributes
+++ b/Source/.gitattributes
@@ -1,6 +1,3 @@
-# Preserve upstream indentation style.
-cm_sha2.* whitespace=indent-with-non-tab
-
# Preserve indentation style in generated code.
cmListFileLexer.c whitespace=-tab-in-indent,-indent-with-non-tab
cmFortranLexer.cxx whitespace=-tab-in-indent,-indent-with-non-tab
diff --git a/Source/CMakeLists.txt b/Source/CMakeLists.txt
index cf9dbb8..718b022 100644
--- a/Source/CMakeLists.txt
+++ b/Source/CMakeLists.txt
@@ -626,8 +626,6 @@ set(SRCS
cm_auto_ptr.hxx
cm_get_date.h
cm_get_date.c
- cm_sha2.h
- cm_sha2.c
cm_utf8.h
cm_utf8.c
cm_codecvt.hxx
@@ -788,6 +786,7 @@ target_link_libraries(CMakeLib cmsys
${CMAKE_CURL_LIBRARIES}
${CMAKE_JSONCPP_LIBRARIES}
${CMAKE_LIBUV_LIBRARIES}
+ ${CMAKE_LIBRHASH_LIBRARIES}
${CMake_KWIML_LIBRARIES}
)
diff --git a/Source/CPack/WiX/cmCPackWIXGenerator.cxx b/Source/CPack/WiX/cmCPackWIXGenerator.cxx
index 4c8abd9..0c4f573 100644
--- a/Source/CPack/WiX/cmCPackWIXGenerator.cxx
+++ b/Source/CPack/WiX/cmCPackWIXGenerator.cxx
@@ -1060,8 +1060,8 @@ std::string cmCPackWIXGenerator::CreateNewIdForPath(std::string const& path)
std::string cmCPackWIXGenerator::CreateHashedId(
std::string const& path, std::string const& normalizedFilename)
{
- CM_AUTO_PTR<cmCryptoHash> sha1 = cmCryptoHash::New("SHA1");
- std::string hash = sha1->HashString(path.c_str());
+ cmCryptoHash sha1(cmCryptoHash::AlgoSHA1);
+ std::string const hash = sha1.HashString(path);
std::string identifier;
identifier += hash.substr(0, 7) + "_";
diff --git a/Source/CTest/cmCTestLaunch.cxx b/Source/CTest/cmCTestLaunch.cxx
index 224681a..f7a6e0b 100644
--- a/Source/CTest/cmCTestLaunch.cxx
+++ b/Source/CTest/cmCTestLaunch.cxx
@@ -4,6 +4,7 @@
#include <cmConfigure.h>
+#include "cmCryptoHash.h"
#include "cmGeneratedFileStream.h"
#include "cmGlobalGenerator.h"
#include "cmMakefile.h"
@@ -14,7 +15,6 @@
#include <cm_auto_ptr.hxx>
#include <cmsys/FStream.hxx>
-#include <cmsys/MD5.h>
#include <cmsys/Process.h>
#include <cmsys/RegularExpression.hxx>
#include <iostream>
@@ -167,17 +167,14 @@ void cmCTestLaunch::ComputeFileNames()
// We hash the input command working dir and command line to obtain
// a repeatable and (probably) unique name for log files.
- char hash[32];
- cmsysMD5* md5 = cmsysMD5_New();
- cmsysMD5_Initialize(md5);
- cmsysMD5_Append(md5, (unsigned char const*)(this->CWD.c_str()), -1);
+ cmCryptoHash md5(cmCryptoHash::AlgoMD5);
+ md5.Initialize();
+ md5.Append(this->CWD);
for (std::vector<std::string>::const_iterator ai = this->RealArgs.begin();
ai != this->RealArgs.end(); ++ai) {
- cmsysMD5_Append(md5, (unsigned char const*)ai->c_str(), -1);
+ md5.Append(*ai);
}
- cmsysMD5_FinalizeHex(md5, hash);
- cmsysMD5_Delete(md5);
- this->LogHash.assign(hash, 32);
+ this->LogHash = md5.FinalizeHex();
// We store stdout and stderr in temporary log files.
this->LogOut = this->LogDir;
diff --git a/Source/Modules/FindLibRHash.cmake b/Source/Modules/FindLibRHash.cmake
new file mode 100644
index 0000000..86c6189
--- /dev/null
+++ b/Source/Modules/FindLibRHash.cmake
@@ -0,0 +1,73 @@
+# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+# file Copyright.txt or https://cmake.org/licensing for details.
+
+#[=======================================================================[.rst:
+FindLibRHash
+------------
+
+Find LibRHash include directory and library.
+
+Imported Targets
+^^^^^^^^^^^^^^^^
+
+An :ref:`imported target <Imported targets>` named
+``LibRHash::LibRHash`` is provided if LibRHash has been found.
+
+Result Variables
+^^^^^^^^^^^^^^^^
+
+This module defines the following variables:
+
+``LibRHash_FOUND``
+ True if LibRHash was found, false otherwise.
+``LibRHash_INCLUDE_DIRS``
+ Include directories needed to include LibRHash headers.
+``LibRHash_LIBRARIES``
+ Libraries needed to link to LibRHash.
+
+Cache Variables
+^^^^^^^^^^^^^^^
+
+This module uses the following cache variables:
+
+``LibRHash_LIBRARY``
+ The location of the LibRHash library file.
+``LibRHash_INCLUDE_DIR``
+ The location of the LibRHash include directory containing ``rhash.h``.
+
+The cache variables should not be used by project code.
+They may be set by end users to point at LibRHash components.
+#]=======================================================================]
+
+#-----------------------------------------------------------------------------
+find_library(LibRHash_LIBRARY
+ NAMES rhash
+ )
+mark_as_advanced(LibRHash_LIBRARY)
+
+find_path(LibRHash_INCLUDE_DIR
+ NAMES rhash.h
+ )
+mark_as_advanced(LibRHash_INCLUDE_DIR)
+
+#-----------------------------------------------------------------------------
+include(${CMAKE_CURRENT_LIST_DIR}/../../Modules/FindPackageHandleStandardArgs.cmake)
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(LibRHash
+ FOUND_VAR LibRHash_FOUND
+ REQUIRED_VARS LibRHash_LIBRARY LibRHash_INCLUDE_DIR
+ )
+set(LIBRHASH_FOUND ${LibRHash_FOUND})
+
+#-----------------------------------------------------------------------------
+# Provide documented result variables and targets.
+if(LibRHash_FOUND)
+ set(LibRHash_INCLUDE_DIRS ${LibRHash_INCLUDE_DIR})
+ set(LibRHash_LIBRARIES ${LibRHash_LIBRARY})
+ if(NOT TARGET LibRHash::LibRHash)
+ add_library(LibRHash::LibRHash UNKNOWN IMPORTED)
+ set_target_properties(LibRHash::LibRHash PROPERTIES
+ IMPORTED_LOCATION "${LibRHash_LIBRARY}"
+ INTERFACE_INCLUDE_DIRECTORIES "${LibRHash_INCLUDE_DIRS}"
+ )
+ endif()
+endif()
diff --git a/Source/cmCryptoHash.cxx b/Source/cmCryptoHash.cxx
index 9b3f84a..f440999 100644
--- a/Source/cmCryptoHash.cxx
+++ b/Source/cmCryptoHash.cxx
@@ -2,31 +2,62 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmCryptoHash.h"
-#include "cm_sha2.h"
-
+#include <cm_kwiml.h>
+#include <cm_rhash.h>
#include <cmsys/FStream.hxx>
-#include <cmsys/MD5.h>
#include <string.h>
+static unsigned int const cmCryptoHashAlgoToId[] = {
+ /* clang-format needs this comment to break after the opening brace */
+ RHASH_MD5, //
+ RHASH_SHA1, //
+ RHASH_SHA224, //
+ RHASH_SHA256, //
+ RHASH_SHA384, //
+ RHASH_SHA512
+};
+
+static int cmCryptoHash_rhash_library_initialized;
+
+static rhash cmCryptoHash_rhash_init(unsigned int id)
+{
+ if (!cmCryptoHash_rhash_library_initialized) {
+ cmCryptoHash_rhash_library_initialized = 1;
+ rhash_library_init();
+ }
+ return rhash_init(id);
+}
+
+cmCryptoHash::cmCryptoHash(Algo algo)
+ : Id(cmCryptoHashAlgoToId[algo])
+ , CTX(cmCryptoHash_rhash_init(Id))
+{
+}
+
+cmCryptoHash::~cmCryptoHash()
+{
+ rhash_free(this->CTX);
+}
+
CM_AUTO_PTR<cmCryptoHash> cmCryptoHash::New(const char* algo)
{
if (strcmp(algo, "MD5") == 0) {
- return CM_AUTO_PTR<cmCryptoHash>(new cmCryptoHashMD5);
+ return CM_AUTO_PTR<cmCryptoHash>(new cmCryptoHash(AlgoMD5));
}
if (strcmp(algo, "SHA1") == 0) {
- return CM_AUTO_PTR<cmCryptoHash>(new cmCryptoHashSHA1);
+ return CM_AUTO_PTR<cmCryptoHash>(new cmCryptoHash(AlgoSHA1));
}
if (strcmp(algo, "SHA224") == 0) {
- return CM_AUTO_PTR<cmCryptoHash>(new cmCryptoHashSHA224);
+ return CM_AUTO_PTR<cmCryptoHash>(new cmCryptoHash(AlgoSHA224));
}
if (strcmp(algo, "SHA256") == 0) {
- return CM_AUTO_PTR<cmCryptoHash>(new cmCryptoHashSHA256);
+ return CM_AUTO_PTR<cmCryptoHash>(new cmCryptoHash(AlgoSHA256));
}
if (strcmp(algo, "SHA384") == 0) {
- return CM_AUTO_PTR<cmCryptoHash>(new cmCryptoHashSHA384);
+ return CM_AUTO_PTR<cmCryptoHash>(new cmCryptoHash(AlgoSHA384));
}
if (strcmp(algo, "SHA512") == 0) {
- return CM_AUTO_PTR<cmCryptoHash>(new cmCryptoHashSHA512);
+ return CM_AUTO_PTR<cmCryptoHash>(new cmCryptoHash(AlgoSHA512));
}
return CM_AUTO_PTR<cmCryptoHash>(CM_NULLPTR);
}
@@ -80,7 +111,7 @@ std::vector<unsigned char> cmCryptoHash::ByteHashFile(const std::string& file)
this->Initialize();
{
// Should be efficient enough on most system:
- cm_sha2_uint64_t buffer[512];
+ KWIML_INT_uint64_t buffer[512];
char* buffer_c = reinterpret_cast<char*>(buffer);
unsigned char const* buffer_uc =
reinterpret_cast<unsigned char const*>(buffer);
@@ -117,51 +148,29 @@ std::string cmCryptoHash::HashFile(const std::string& file)
return ByteHashToString(this->ByteHashFile(file));
}
-cmCryptoHashMD5::cmCryptoHashMD5()
- : MD5(cmsysMD5_New())
+void cmCryptoHash::Initialize()
{
+ rhash_reset(this->CTX);
}
-cmCryptoHashMD5::~cmCryptoHashMD5()
+void cmCryptoHash::Append(void const* buf, size_t sz)
{
- cmsysMD5_Delete(this->MD5);
+ rhash_update(this->CTX, buf, sz);
}
-void cmCryptoHashMD5::Initialize()
+void cmCryptoHash::Append(std::string const& str)
{
- cmsysMD5_Initialize(this->MD5);
+ this->Append(str.c_str(), str.size());
}
-void cmCryptoHashMD5::Append(unsigned char const* buf, int sz)
+std::vector<unsigned char> cmCryptoHash::Finalize()
{
- cmsysMD5_Append(this->MD5, buf, sz);
+ std::vector<unsigned char> hash(rhash_get_digest_size(this->Id), 0);
+ rhash_final(this->CTX, &hash[0]);
+ return hash;
}
-std::vector<unsigned char> cmCryptoHashMD5::Finalize()
+std::string cmCryptoHash::FinalizeHex()
{
- std::vector<unsigned char> hash(16, 0);
- cmsysMD5_Finalize(this->MD5, &hash[0]);
- return hash;
+ return cmCryptoHash::ByteHashToString(this->Finalize());
}
-
-#define cmCryptoHash_SHA_CLASS_IMPL(SHA) \
- cmCryptoHash##SHA::cmCryptoHash##SHA() \
- : SHA(new SHA_CTX) \
- { \
- } \
- cmCryptoHash##SHA::~cmCryptoHash##SHA() { delete this->SHA; } \
- void cmCryptoHash##SHA::Initialize() { SHA##_Init(this->SHA); } \
- void cmCryptoHash##SHA::Append(unsigned char const* buf, int sz) \
- { \
- SHA##_Update(this->SHA, buf, sz); \
- } \
- std::vector<unsigned char> cmCryptoHash##SHA::Finalize() \
- { \
- std::vector<unsigned char> hash(SHA##_DIGEST_LENGTH, 0); \
- SHA##_Final(&hash[0], this->SHA); \
- return hash; \
- }
-
-cmCryptoHash_SHA_CLASS_IMPL(SHA1) cmCryptoHash_SHA_CLASS_IMPL(SHA224)
- cmCryptoHash_SHA_CLASS_IMPL(SHA256) cmCryptoHash_SHA_CLASS_IMPL(SHA384)
- cmCryptoHash_SHA_CLASS_IMPL(SHA512)
diff --git a/Source/cmCryptoHash.h b/Source/cmCryptoHash.h
index 5c2d3ca..95080ac 100644
--- a/Source/cmCryptoHash.h
+++ b/Source/cmCryptoHash.h
@@ -15,7 +15,18 @@
class cmCryptoHash
{
public:
- virtual ~cmCryptoHash() {}
+ enum Algo
+ {
+ AlgoMD5,
+ AlgoSHA1,
+ AlgoSHA224,
+ AlgoSHA256,
+ AlgoSHA384,
+ AlgoSHA512
+ };
+
+ cmCryptoHash(Algo algo);
+ ~cmCryptoHash();
/// @brief Returns a new hash generator of the requested type
/// @arg algo Hash type name. Supported hash types are
@@ -53,47 +64,15 @@ public:
/// An empty string otherwise.
std::string HashFile(const std::string& file);
-protected:
- virtual void Initialize() = 0;
- virtual void Append(unsigned char const*, int) = 0;
- virtual std::vector<unsigned char> Finalize() = 0;
-};
-
-class cmCryptoHashMD5 : public cmCryptoHash
-{
- struct cmsysMD5_s* MD5;
-
-public:
- cmCryptoHashMD5();
- ~cmCryptoHashMD5() CM_OVERRIDE;
+ void Initialize();
+ void Append(void const*, size_t);
+ void Append(std::string const& str);
+ std::vector<unsigned char> Finalize();
+ std::string FinalizeHex();
-protected:
- void Initialize() CM_OVERRIDE;
- void Append(unsigned char const* buf, int sz) CM_OVERRIDE;
- std::vector<unsigned char> Finalize() CM_OVERRIDE;
+private:
+ unsigned int Id;
+ struct rhash_context* CTX;
};
-#define cmCryptoHash_SHA_CLASS_DECL(SHA) \
- class cmCryptoHash##SHA : public cmCryptoHash \
- { \
- union _SHA_CTX* SHA; \
- \
- public: \
- cmCryptoHash##SHA(); \
- ~cmCryptoHash##SHA(); \
- \
- protected: \
- virtual void Initialize(); \
- virtual void Append(unsigned char const* buf, int sz); \
- virtual std::vector<unsigned char> Finalize(); \
- }
-
-cmCryptoHash_SHA_CLASS_DECL(SHA1);
-cmCryptoHash_SHA_CLASS_DECL(SHA224);
-cmCryptoHash_SHA_CLASS_DECL(SHA256);
-cmCryptoHash_SHA_CLASS_DECL(SHA384);
-cmCryptoHash_SHA_CLASS_DECL(SHA512);
-
-#undef cmCryptoHash_SHA_CLASS_DECL
-
#endif
diff --git a/Source/cmFileCommand.cxx b/Source/cmFileCommand.cxx
index afff0f3..15257fc 100644
--- a/Source/cmFileCommand.cxx
+++ b/Source/cmFileCommand.cxx
@@ -2554,7 +2554,8 @@ bool cmFileCommand::HandleDownloadCommand(std::vector<std::string> const& args)
this->SetError("DOWNLOAD missing sum value for EXPECTED_MD5.");
return false;
}
- hash = CM_AUTO_PTR<cmCryptoHash>(cmCryptoHash::New("MD5"));
+ hash =
+ CM_AUTO_PTR<cmCryptoHash>(new cmCryptoHash(cmCryptoHash::AlgoMD5));
hashMatchMSG = "MD5 sum";
expectedHash = cmSystemTools::LowerCase(*i);
} else if (*i == "SHOW_PROGRESS") {
diff --git a/Source/cmFilePathUuid.cxx b/Source/cmFilePathUuid.cxx
index ad434e3..03d2524 100644
--- a/Source/cmFilePathUuid.cxx
+++ b/Source/cmFilePathUuid.cxx
@@ -107,8 +107,8 @@ std::string cmFilePathUuid::GetChecksumString(
{
// Calculate the file ( seed + relative path + name ) checksum
std::vector<unsigned char> hashBytes =
- cmCryptoHash::New("SHA256")->ByteHashString(
- sourceRelSeed + sourceRelPath + sourceFilename);
+ cmCryptoHash(cmCryptoHash::AlgoSHA256)
+ .ByteHashString(sourceRelSeed + sourceRelPath + sourceFilename);
checksumBase32 =
cmBase32Encoder().encodeString(&hashBytes[0], hashBytes.size(), false);
diff --git a/Source/cmGlobalGenerator.cxx b/Source/cmGlobalGenerator.cxx
index 2d0767f..fa447ff 100644
--- a/Source/cmGlobalGenerator.cxx
+++ b/Source/cmGlobalGenerator.cxx
@@ -45,9 +45,9 @@
#include "cmake.h"
#if defined(CMAKE_BUILD_WITH_CMAKE)
+#include "cmCryptoHash.h"
#include <cm_jsoncpp_value.h>
#include <cm_jsoncpp_writer.h>
-#include <cmsys/MD5.h>
#endif
class cmInstalledFile;
@@ -2617,14 +2617,9 @@ void cmGlobalGenerator::AddRuleHash(const std::vector<std::string>& outputs,
// Compute a hash of the rule.
RuleHash hash;
{
- unsigned char const* data =
- reinterpret_cast<unsigned char const*>(content.c_str());
- int length = static_cast<int>(content.length());
- cmsysMD5* sum = cmsysMD5_New();
- cmsysMD5_Initialize(sum);
- cmsysMD5_Append(sum, data, length);
- cmsysMD5_FinalizeHex(sum, hash.Data);
- cmsysMD5_Delete(sum);
+ cmCryptoHash md5(cmCryptoHash::AlgoMD5);
+ std::string const md5_hex = md5.HashString(content);
+ memcpy(hash.Data, md5_hex.c_str(), 32);
}
// Shorten the output name (in expected use case).
diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx
index 7d3a2f0..e7dfed5 100644
--- a/Source/cmLocalGenerator.cxx
+++ b/Source/cmLocalGenerator.cxx
@@ -27,7 +27,7 @@
#if defined(CMAKE_BUILD_WITH_CMAKE)
#define CM_LG_ENCODE_OBJECT_NAMES
-#include <cmsys/MD5.h>
+#include "cmCryptoHash.h"
#endif
#include <algorithm>
@@ -2002,17 +2002,6 @@ void cmLocalGenerator::GenerateTargetInstallRules(
}
#if defined(CM_LG_ENCODE_OBJECT_NAMES)
-static std::string cmLocalGeneratorMD5(const char* input)
-{
- char md5out[32];
- cmsysMD5* md5 = cmsysMD5_New();
- cmsysMD5_Initialize(md5);
- cmsysMD5_Append(md5, reinterpret_cast<unsigned char const*>(input), -1);
- cmsysMD5_FinalizeHex(md5, md5out);
- cmsysMD5_Delete(md5);
- return std::string(md5out, 32);
-}
-
static bool cmLocalGeneratorShortenObjectName(std::string& objName,
std::string::size_type max_len)
{
@@ -2021,7 +2010,8 @@ static bool cmLocalGeneratorShortenObjectName(std::string& objName,
std::string::size_type pos =
objName.find('/', objName.size() - max_len + 32);
if (pos != objName.npos) {
- std::string md5name = cmLocalGeneratorMD5(objName.substr(0, pos).c_str());
+ cmCryptoHash md5(cmCryptoHash::AlgoMD5);
+ std::string md5name = md5.HashString(objName.substr(0, pos));
md5name += objName.substr(pos);
objName = md5name;
diff --git a/Source/cmSystemTools.cxx b/Source/cmSystemTools.cxx
index 0a3a1ab..7738ab6 100644
--- a/Source/cmSystemTools.cxx
+++ b/Source/cmSystemTools.cxx
@@ -847,8 +847,8 @@ bool cmSystemTools::RenameFile(const char* oldname, const char* newname)
bool cmSystemTools::ComputeFileMD5(const std::string& source, char* md5out)
{
#if defined(CMAKE_BUILD_WITH_CMAKE)
- cmCryptoHashMD5 md5;
- std::string str = md5.HashFile(source);
+ cmCryptoHash md5(cmCryptoHash::AlgoMD5);
+ std::string const str = md5.HashFile(source);
strncpy(md5out, str.c_str(), 32);
return !str.empty();
#else
@@ -863,7 +863,7 @@ bool cmSystemTools::ComputeFileMD5(const std::string& source, char* md5out)
std::string cmSystemTools::ComputeStringMD5(const std::string& input)
{
#if defined(CMAKE_BUILD_WITH_CMAKE)
- cmCryptoHashMD5 md5;
+ cmCryptoHash md5(cmCryptoHash::AlgoMD5);
return md5.HashString(input);
#else
(void)input;
diff --git a/Source/cmUuid.cxx b/Source/cmUuid.cxx
index 904bcbb..201e1cc 100644
--- a/Source/cmUuid.cxx
+++ b/Source/cmUuid.cxx
@@ -2,9 +2,8 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmUuid.h"
-#include "cm_sha2.h"
+#include "cmCryptoHash.h"
-#include <cmsys/MD5.h>
#include <string.h>
cmUuid::cmUuid()
@@ -22,16 +21,12 @@ std::string cmUuid::FromMd5(std::vector<unsigned char> const& uuidNamespace,
std::vector<unsigned char> hashInput;
this->CreateHashInput(uuidNamespace, name, hashInput);
- cmsysMD5_s* md5 = cmsysMD5_New();
- cmsysMD5_Initialize(md5);
- cmsysMD5_Append(md5, &hashInput[0], int(hashInput.size()));
+ cmCryptoHash md5(cmCryptoHash::AlgoMD5);
+ md5.Initialize();
+ md5.Append(&hashInput[0], hashInput.size());
+ std::vector<unsigned char> digest = md5.Finalize();
- unsigned char digest[16] = { 0 };
- cmsysMD5_Finalize(md5, digest);
-
- cmsysMD5_Delete(md5);
-
- return this->FromDigest(digest, 3);
+ return this->FromDigest(&digest[0], 3);
}
std::string cmUuid::FromSha1(std::vector<unsigned char> const& uuidNamespace,
@@ -40,16 +35,12 @@ std::string cmUuid::FromSha1(std::vector<unsigned char> const& uuidNamespace,
std::vector<unsigned char> hashInput;
this->CreateHashInput(uuidNamespace, name, hashInput);
- SHA_CTX* sha = new SHA_CTX;
- SHA1_Init(sha);
- SHA1_Update(sha, &hashInput[0], hashInput.size());
-
- unsigned char digest[SHA1_DIGEST_LENGTH] = { 0 };
- SHA1_Final(digest, sha);
-
- delete sha;
+ cmCryptoHash sha1(cmCryptoHash::AlgoSHA1);
+ sha1.Initialize();
+ sha1.Append(&hashInput[0], hashInput.size());
+ std::vector<unsigned char> digest = sha1.Finalize();
- return this->FromDigest(digest, 5);
+ return this->FromDigest(&digest[0], 5);
}
void cmUuid::CreateHashInput(std::vector<unsigned char> const& uuidNamespace,
diff --git a/Source/cm_sha2.c b/Source/cm_sha2.c
deleted file mode 100644
index 649c39a..0000000
--- a/Source/cm_sha2.c
+++ /dev/null
@@ -1,1613 +0,0 @@
-/*
- * FILE: sha2.c
- * AUTHOR: Aaron D. Gifford
- * http://www.aarongifford.com/computers/sha.html
- *
- * Copyright (c) 2000-2003, Aaron D. Gifford
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the copyright holder nor the names of contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTOR(S) ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTOR(S) BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $Id: sha2.c,v 1.4 2004/01/07 22:58:18 adg Exp $
- */
-
-#include <string.h> /* memcpy()/memset() or bcopy()/bzero() */
-#include <assert.h> /* assert() */
-#include "cm_sha2.h" /* "sha2.h" -> "cm_sha2.h" renamed for CMake */
-
-/*
- * ASSERT NOTE:
- * Some sanity checking code is included using assert(). On my FreeBSD
- * system, this additional code can be removed by compiling with NDEBUG
- * defined. Check your own systems manpage on assert() to see how to
- * compile WITHOUT the sanity checking code on your system.
- *
- * UNROLLED TRANSFORM LOOP NOTE:
- * You can define SHA2_UNROLL_TRANSFORM to use the unrolled transform
- * loop version for the hash transform rounds (defined using macros
- * later in this file). Either define on the command line, for example:
- *
- * cc -DSHA2_UNROLL_TRANSFORM -o sha2 sha2.c sha2prog.c
- *
- * or define below:
- *
- * #define SHA2_UNROLL_TRANSFORM
- *
- */
-
-
-/*** SHA-224/256/384/512 Machine Architecture Definitions *************/
-/*
- * BYTE_ORDER NOTE:
- *
- * Please make sure that your system defines BYTE_ORDER. If your
- * architecture is little-endian, make sure it also defines
- * LITTLE_ENDIAN and that the two (BYTE_ORDER and LITTLE_ENDIAN) are
- * equivilent.
- *
- * If your system does not define the above, then you can do so by
- * hand like this:
- *
- * #define LITTLE_ENDIAN 1234
- * #define BIG_ENDIAN 4321
- *
- * And for little-endian machines, add:
- *
- * #define BYTE_ORDER LITTLE_ENDIAN
- *
- * Or for big-endian machines:
- *
- * #define BYTE_ORDER BIG_ENDIAN
- *
- * The FreeBSD machine this was written on defines BYTE_ORDER
- * appropriately by including <sys/types.h> (which in turn includes
- * <machine/endian.h> where the appropriate definitions are actually
- * made).
- */
-#if !defined(BYTE_ORDER) || (BYTE_ORDER != LITTLE_ENDIAN && BYTE_ORDER != BIG_ENDIAN)
-/* CMake modification: use byte order from KWIML. */
-# undef BYTE_ORDER
-# undef BIG_ENDIAN
-# undef LITTLE_ENDIAN
-# define BYTE_ORDER KWIML_ABI_ENDIAN_ID
-# define BIG_ENDIAN KWIML_ABI_ENDIAN_ID_BIG
-# define LITTLE_ENDIAN KWIML_ABI_ENDIAN_ID_LITTLE
-#endif
-
-/* CMake modification: use types computed in header. */
-typedef cm_sha2_uint8_t sha_byte; /* Exactly 1 byte */
-typedef cm_sha2_uint32_t sha_word32; /* Exactly 4 bytes */
-typedef cm_sha2_uint64_t sha_word64; /* Exactly 8 bytes */
-#define SHA_UINT32_C(x) KWIML_INT_UINT32_C(x)
-#define SHA_UINT64_C(x) KWIML_INT_UINT64_C(x)
-#if defined(__clang__)
-# pragma clang diagnostic ignored "-Wcast-align"
-#endif
-
-/*** ENDIAN REVERSAL MACROS *******************************************/
-#if BYTE_ORDER == LITTLE_ENDIAN
-#define REVERSE32(w,x) { \
- sha_word32 tmp = (w); \
- tmp = (tmp >> 16) | (tmp << 16); \
- (x) = ((tmp & SHA_UINT32_C(0xff00ff00)) >> 8) | \
- ((tmp & SHA_UINT32_C(0x00ff00ff)) << 8); \
-}
-#define REVERSE64(w,x) { \
- sha_word64 tmp = (w); \
- tmp = (tmp >> 32) | (tmp << 32); \
- tmp = ((tmp & SHA_UINT64_C(0xff00ff00ff00ff00)) >> 8) | \
- ((tmp & SHA_UINT64_C(0x00ff00ff00ff00ff)) << 8); \
- (x) = ((tmp & SHA_UINT64_C(0xffff0000ffff0000)) >> 16) | \
- ((tmp & SHA_UINT64_C(0x0000ffff0000ffff)) << 16); \
-}
-#endif /* BYTE_ORDER == LITTLE_ENDIAN */
-
-/*
- * Macro for incrementally adding the unsigned 64-bit integer n to the
- * unsigned 128-bit integer (represented using a two-element array of
- * 64-bit words):
- */
-#define ADDINC128(w,n) { \
- (w)[0] += (sha_word64)(n); \
- if ((w)[0] < (n)) { \
- (w)[1]++; \
- } \
-}
-
-/*
- * Macros for copying blocks of memory and for zeroing out ranges
- * of memory. Using these macros makes it easy to switch from
- * using memset()/memcpy() and using bzero()/bcopy().
- *
- * Please define either SHA2_USE_MEMSET_MEMCPY or define
- * SHA2_USE_BZERO_BCOPY depending on which function set you
- * choose to use:
- */
-#if !defined(SHA2_USE_MEMSET_MEMCPY) && !defined(SHA2_USE_BZERO_BCOPY)
-/* Default to memset()/memcpy() if no option is specified */
-#define SHA2_USE_MEMSET_MEMCPY 1
-#endif
-#if defined(SHA2_USE_MEMSET_MEMCPY) && defined(SHA2_USE_BZERO_BCOPY)
-/* Abort with an error if BOTH options are defined */
-#error Define either SHA2_USE_MEMSET_MEMCPY or SHA2_USE_BZERO_BCOPY, not both!
-#endif
-
-#ifdef SHA2_USE_MEMSET_MEMCPY
-#define MEMSET_BZERO(p,l) memset((p), 0, (l))
-#define MEMCPY_BCOPY(d,s,l) memcpy((d), (s), (l))
-#endif
-#ifdef SHA2_USE_BZERO_BCOPY
-#define MEMSET_BZERO(p,l) bzero((p), (l))
-#define MEMCPY_BCOPY(d,s,l) bcopy((s), (d), (l))
-#endif
-
-
-/*** THE SIX LOGICAL FUNCTIONS ****************************************/
-/*
- * Bit shifting and rotation (used by the six SHA-XYZ logical functions:
- *
- * NOTE: In the original SHA-256/384/512 document, the shift-right
- * function was named R and the rotate-right function was called S.
- * (See: http://csrc.nist.gov/cryptval/shs/sha256-384-512.pdf on the
- * web.)
- *
- * The newer NIST FIPS 180-2 document uses a much clearer naming
- * scheme, SHR for shift-right, ROTR for rotate-right, and ROTL for
- * rotate-left. (See:
- * http://csrc.nist.gov/publications/fips/fips180-2/fips180-2.pdf
- * on the web.)
- *
- * WARNING: These macros must be used cautiously, since they reference
- * supplied parameters sometimes more than once, and thus could have
- * unexpected side-effects if used without taking this into account.
- */
-/* Shift-right (used in SHA-256, SHA-384, and SHA-512): */
-#define SHR(b,x) ((x) >> (b))
-/* 32-bit Rotate-right (used in SHA-256): */
-#define ROTR32(b,x) (((x) >> (b)) | ((x) << (32 - (b))))
-/* 64-bit Rotate-right (used in SHA-384 and SHA-512): */
-#define ROTR64(b,x) (((x) >> (b)) | ((x) << (64 - (b))))
-/* 32-bit Rotate-left (used in SHA-1): */
-#define ROTL32(b,x) (((x) << (b)) | ((x) >> (32 - (b))))
-
-/* Two logical functions used in SHA-1, SHA-254, SHA-256, SHA-384, and SHA-512: */
-#define Ch(x,y,z) (((x) & (y)) ^ ((~(x)) & (z)))
-#define Maj(x,y,z) (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z)))
-
-/* Function used in SHA-1: */
-#define Parity(x,y,z) ((x) ^ (y) ^ (z))
-
-/* Four logical functions used in SHA-256: */
-#define Sigma0_256(x) (ROTR32(2, (x)) ^ ROTR32(13, (x)) ^ ROTR32(22, (x)))
-#define Sigma1_256(x) (ROTR32(6, (x)) ^ ROTR32(11, (x)) ^ ROTR32(25, (x)))
-#define sigma0_256(x) (ROTR32(7, (x)) ^ ROTR32(18, (x)) ^ SHR( 3 , (x)))
-#define sigma1_256(x) (ROTR32(17, (x)) ^ ROTR32(19, (x)) ^ SHR( 10, (x)))
-
-/* Four of six logical functions used in SHA-384 and SHA-512: */
-#define Sigma0_512(x) (ROTR64(28, (x)) ^ ROTR64(34, (x)) ^ ROTR64(39, (x)))
-#define Sigma1_512(x) (ROTR64(14, (x)) ^ ROTR64(18, (x)) ^ ROTR64(41, (x)))
-#define sigma0_512(x) (ROTR64( 1, (x)) ^ ROTR64( 8, (x)) ^ SHR( 7, (x)))
-#define sigma1_512(x) (ROTR64(19, (x)) ^ ROTR64(61, (x)) ^ SHR( 6, (x)))
-
-/*** INTERNAL FUNCTION PROTOTYPES *************************************/
-
-/* SHA-224 and SHA-256: */
-void SHA256_Internal_Init(SHA_CTX*, const sha_word32*);
-void SHA256_Internal_Last(SHA_CTX*);
-void SHA256_Internal_Transform(SHA_CTX*, const sha_word32*);
-
-/* SHA-384 and SHA-512: */
-void SHA512_Internal_Init(SHA_CTX*, const sha_word64*);
-void SHA512_Internal_Last(SHA_CTX*);
-void SHA512_Internal_Transform(SHA_CTX*, const sha_word64*);
-
-
-/*** SHA2 INITIAL HASH VALUES AND CONSTANTS ***************************/
-
-/* Hash constant words K for SHA-1: */
-#define K1_0_TO_19 SHA_UINT32_C(0x5a827999)
-#define K1_20_TO_39 SHA_UINT32_C(0x6ed9eba1)
-#define K1_40_TO_59 SHA_UINT32_C(0x8f1bbcdc)
-#define K1_60_TO_79 SHA_UINT32_C(0xca62c1d6)
-
-/* Initial hash value H for SHA-1: */
-static const sha_word32 sha1_initial_hash_value[5] = {
- SHA_UINT32_C(0x67452301),
- SHA_UINT32_C(0xefcdab89),
- SHA_UINT32_C(0x98badcfe),
- SHA_UINT32_C(0x10325476),
- SHA_UINT32_C(0xc3d2e1f0)
-};
-
-/* Hash constant words K for SHA-224 and SHA-256: */
-static const sha_word32 K256[64] = {
- SHA_UINT32_C(0x428a2f98), SHA_UINT32_C(0x71374491),
- SHA_UINT32_C(0xb5c0fbcf), SHA_UINT32_C(0xe9b5dba5),
- SHA_UINT32_C(0x3956c25b), SHA_UINT32_C(0x59f111f1),
- SHA_UINT32_C(0x923f82a4), SHA_UINT32_C(0xab1c5ed5),
- SHA_UINT32_C(0xd807aa98), SHA_UINT32_C(0x12835b01),
- SHA_UINT32_C(0x243185be), SHA_UINT32_C(0x550c7dc3),
- SHA_UINT32_C(0x72be5d74), SHA_UINT32_C(0x80deb1fe),
- SHA_UINT32_C(0x9bdc06a7), SHA_UINT32_C(0xc19bf174),
- SHA_UINT32_C(0xe49b69c1), SHA_UINT32_C(0xefbe4786),
- SHA_UINT32_C(0x0fc19dc6), SHA_UINT32_C(0x240ca1cc),
- SHA_UINT32_C(0x2de92c6f), SHA_UINT32_C(0x4a7484aa),
- SHA_UINT32_C(0x5cb0a9dc), SHA_UINT32_C(0x76f988da),
- SHA_UINT32_C(0x983e5152), SHA_UINT32_C(0xa831c66d),
- SHA_UINT32_C(0xb00327c8), SHA_UINT32_C(0xbf597fc7),
- SHA_UINT32_C(0xc6e00bf3), SHA_UINT32_C(0xd5a79147),
- SHA_UINT32_C(0x06ca6351), SHA_UINT32_C(0x14292967),
- SHA_UINT32_C(0x27b70a85), SHA_UINT32_C(0x2e1b2138),
- SHA_UINT32_C(0x4d2c6dfc), SHA_UINT32_C(0x53380d13),
- SHA_UINT32_C(0x650a7354), SHA_UINT32_C(0x766a0abb),
- SHA_UINT32_C(0x81c2c92e), SHA_UINT32_C(0x92722c85),
- SHA_UINT32_C(0xa2bfe8a1), SHA_UINT32_C(0xa81a664b),
- SHA_UINT32_C(0xc24b8b70), SHA_UINT32_C(0xc76c51a3),
- SHA_UINT32_C(0xd192e819), SHA_UINT32_C(0xd6990624),
- SHA_UINT32_C(0xf40e3585), SHA_UINT32_C(0x106aa070),
- SHA_UINT32_C(0x19a4c116), SHA_UINT32_C(0x1e376c08),
- SHA_UINT32_C(0x2748774c), SHA_UINT32_C(0x34b0bcb5),
- SHA_UINT32_C(0x391c0cb3), SHA_UINT32_C(0x4ed8aa4a),
- SHA_UINT32_C(0x5b9cca4f), SHA_UINT32_C(0x682e6ff3),
- SHA_UINT32_C(0x748f82ee), SHA_UINT32_C(0x78a5636f),
- SHA_UINT32_C(0x84c87814), SHA_UINT32_C(0x8cc70208),
- SHA_UINT32_C(0x90befffa), SHA_UINT32_C(0xa4506ceb),
- SHA_UINT32_C(0xbef9a3f7), SHA_UINT32_C(0xc67178f2)
-};
-
-/* Initial hash value H for SHA-224: */
-static const sha_word32 sha224_initial_hash_value[8] = {
- SHA_UINT32_C(0xc1059ed8),
- SHA_UINT32_C(0x367cd507),
- SHA_UINT32_C(0x3070dd17),
- SHA_UINT32_C(0xf70e5939),
- SHA_UINT32_C(0xffc00b31),
- SHA_UINT32_C(0x68581511),
- SHA_UINT32_C(0x64f98fa7),
- SHA_UINT32_C(0xbefa4fa4)
-};
-
-/* Initial hash value H for SHA-256: */
-static const sha_word32 sha256_initial_hash_value[8] = {
- SHA_UINT32_C(0x6a09e667),
- SHA_UINT32_C(0xbb67ae85),
- SHA_UINT32_C(0x3c6ef372),
- SHA_UINT32_C(0xa54ff53a),
- SHA_UINT32_C(0x510e527f),
- SHA_UINT32_C(0x9b05688c),
- SHA_UINT32_C(0x1f83d9ab),
- SHA_UINT32_C(0x5be0cd19)
-};
-
-/* Hash constant words K for SHA-384 and SHA-512: */
-static const sha_word64 K512[80] = {
- SHA_UINT64_C(0x428a2f98d728ae22), SHA_UINT64_C(0x7137449123ef65cd),
- SHA_UINT64_C(0xb5c0fbcfec4d3b2f), SHA_UINT64_C(0xe9b5dba58189dbbc),
- SHA_UINT64_C(0x3956c25bf348b538), SHA_UINT64_C(0x59f111f1b605d019),
- SHA_UINT64_C(0x923f82a4af194f9b), SHA_UINT64_C(0xab1c5ed5da6d8118),
- SHA_UINT64_C(0xd807aa98a3030242), SHA_UINT64_C(0x12835b0145706fbe),
- SHA_UINT64_C(0x243185be4ee4b28c), SHA_UINT64_C(0x550c7dc3d5ffb4e2),
- SHA_UINT64_C(0x72be5d74f27b896f), SHA_UINT64_C(0x80deb1fe3b1696b1),
- SHA_UINT64_C(0x9bdc06a725c71235), SHA_UINT64_C(0xc19bf174cf692694),
- SHA_UINT64_C(0xe49b69c19ef14ad2), SHA_UINT64_C(0xefbe4786384f25e3),
- SHA_UINT64_C(0x0fc19dc68b8cd5b5), SHA_UINT64_C(0x240ca1cc77ac9c65),
- SHA_UINT64_C(0x2de92c6f592b0275), SHA_UINT64_C(0x4a7484aa6ea6e483),
- SHA_UINT64_C(0x5cb0a9dcbd41fbd4), SHA_UINT64_C(0x76f988da831153b5),
- SHA_UINT64_C(0x983e5152ee66dfab), SHA_UINT64_C(0xa831c66d2db43210),
- SHA_UINT64_C(0xb00327c898fb213f), SHA_UINT64_C(0xbf597fc7beef0ee4),
- SHA_UINT64_C(0xc6e00bf33da88fc2), SHA_UINT64_C(0xd5a79147930aa725),
- SHA_UINT64_C(0x06ca6351e003826f), SHA_UINT64_C(0x142929670a0e6e70),
- SHA_UINT64_C(0x27b70a8546d22ffc), SHA_UINT64_C(0x2e1b21385c26c926),
- SHA_UINT64_C(0x4d2c6dfc5ac42aed), SHA_UINT64_C(0x53380d139d95b3df),
- SHA_UINT64_C(0x650a73548baf63de), SHA_UINT64_C(0x766a0abb3c77b2a8),
- SHA_UINT64_C(0x81c2c92e47edaee6), SHA_UINT64_C(0x92722c851482353b),
- SHA_UINT64_C(0xa2bfe8a14cf10364), SHA_UINT64_C(0xa81a664bbc423001),
- SHA_UINT64_C(0xc24b8b70d0f89791), SHA_UINT64_C(0xc76c51a30654be30),
- SHA_UINT64_C(0xd192e819d6ef5218), SHA_UINT64_C(0xd69906245565a910),
- SHA_UINT64_C(0xf40e35855771202a), SHA_UINT64_C(0x106aa07032bbd1b8),
- SHA_UINT64_C(0x19a4c116b8d2d0c8), SHA_UINT64_C(0x1e376c085141ab53),
- SHA_UINT64_C(0x2748774cdf8eeb99), SHA_UINT64_C(0x34b0bcb5e19b48a8),
- SHA_UINT64_C(0x391c0cb3c5c95a63), SHA_UINT64_C(0x4ed8aa4ae3418acb),
- SHA_UINT64_C(0x5b9cca4f7763e373), SHA_UINT64_C(0x682e6ff3d6b2b8a3),
- SHA_UINT64_C(0x748f82ee5defb2fc), SHA_UINT64_C(0x78a5636f43172f60),
- SHA_UINT64_C(0x84c87814a1f0ab72), SHA_UINT64_C(0x8cc702081a6439ec),
- SHA_UINT64_C(0x90befffa23631e28), SHA_UINT64_C(0xa4506cebde82bde9),
- SHA_UINT64_C(0xbef9a3f7b2c67915), SHA_UINT64_C(0xc67178f2e372532b),
- SHA_UINT64_C(0xca273eceea26619c), SHA_UINT64_C(0xd186b8c721c0c207),
- SHA_UINT64_C(0xeada7dd6cde0eb1e), SHA_UINT64_C(0xf57d4f7fee6ed178),
- SHA_UINT64_C(0x06f067aa72176fba), SHA_UINT64_C(0x0a637dc5a2c898a6),
- SHA_UINT64_C(0x113f9804bef90dae), SHA_UINT64_C(0x1b710b35131c471b),
- SHA_UINT64_C(0x28db77f523047d84), SHA_UINT64_C(0x32caab7b40c72493),
- SHA_UINT64_C(0x3c9ebe0a15c9bebc), SHA_UINT64_C(0x431d67c49c100d4c),
- SHA_UINT64_C(0x4cc5d4becb3e42b6), SHA_UINT64_C(0x597f299cfc657e2a),
- SHA_UINT64_C(0x5fcb6fab3ad6faec), SHA_UINT64_C(0x6c44198c4a475817)
-};
-
-/* Initial hash value H for SHA-384 */
-static const sha_word64 sha384_initial_hash_value[8] = {
- SHA_UINT64_C(0xcbbb9d5dc1059ed8),
- SHA_UINT64_C(0x629a292a367cd507),
- SHA_UINT64_C(0x9159015a3070dd17),
- SHA_UINT64_C(0x152fecd8f70e5939),
- SHA_UINT64_C(0x67332667ffc00b31),
- SHA_UINT64_C(0x8eb44a8768581511),
- SHA_UINT64_C(0xdb0c2e0d64f98fa7),
- SHA_UINT64_C(0x47b5481dbefa4fa4)
-};
-
-/* Initial hash value H for SHA-512 */
-static const sha_word64 sha512_initial_hash_value[8] = {
- SHA_UINT64_C(0x6a09e667f3bcc908),
- SHA_UINT64_C(0xbb67ae8584caa73b),
- SHA_UINT64_C(0x3c6ef372fe94f82b),
- SHA_UINT64_C(0xa54ff53a5f1d36f1),
- SHA_UINT64_C(0x510e527fade682d1),
- SHA_UINT64_C(0x9b05688c2b3e6c1f),
- SHA_UINT64_C(0x1f83d9abfb41bd6b),
- SHA_UINT64_C(0x5be0cd19137e2179)
-};
-
-/*
- * Constant used by SHA224/256/384/512_End() functions for converting the
- * digest to a readable hexadecimal character string:
- */
-static const char *sha_hex_digits = "0123456789abcdef";
-
-
-/*** SHA-1: ***********************************************************/
-void SHA1_Init(SHA_CTX* context) {
- /* Sanity check: */
- assert(context != (SHA_CTX*)0);
-
- MEMCPY_BCOPY(context->s1.state, sha1_initial_hash_value, sizeof(sha_word32) * 5);
- MEMSET_BZERO(context->s1.buffer, 64);
- context->s1.bitcount = 0;
-}
-
-#ifdef SHA2_UNROLL_TRANSFORM
-
-/* Unrolled SHA-1 round macros: */
-
-#if BYTE_ORDER == LITTLE_ENDIAN
-
-#define ROUND1_0_TO_15(a,b,c,d,e) \
- REVERSE32(*data++, W1[j]); \
- (e) = ROTL32(5, (a)) + Ch((b), (c), (d)) + (e) + \
- K1_0_TO_19 + W1[j]; \
- (b) = ROTL32(30, (b)); \
- j++;
-
-#else /* BYTE_ORDER == LITTLE_ENDIAN */
-
-#define ROUND1_0_TO_15(a,b,c,d,e) \
- (e) = ROTL32(5, (a)) + Ch((b), (c), (d)) + (e) + \
- K1_0_TO_19 + ( W1[j] = *data++ ); \
- (b) = ROTL32(30, (b)); \
- j++;
-
-#endif /* BYTE_ORDER == LITTLE_ENDIAN */
-
-#define ROUND1_16_TO_19(a,b,c,d,e) \
- T1 = W1[(j+13)&0x0f] ^ W1[(j+8)&0x0f] ^ W1[(j+2)&0x0f] ^ W1[j&0x0f]; \
- (e) = ROTL32(5, a) + Ch(b,c,d) + e + K1_0_TO_19 + ( W1[j&0x0f] = ROTL32(1, T1) ); \
- (b) = ROTL32(30, b); \
- j++;
-
-#define ROUND1_20_TO_39(a,b,c,d,e) \
- T1 = W1[(j+13)&0x0f] ^ W1[(j+8)&0x0f] ^ W1[(j+2)&0x0f] ^ W1[j&0x0f]; \
- (e) = ROTL32(5, a) + Parity(b,c,d) + e + K1_20_TO_39 + ( W1[j&0x0f] = ROTL32(1, T1) ); \
- (b) = ROTL32(30, b); \
- j++;
-
-#define ROUND1_40_TO_59(a,b,c,d,e) \
- T1 = W1[(j+13)&0x0f] ^ W1[(j+8)&0x0f] ^ W1[(j+2)&0x0f] ^ W1[j&0x0f]; \
- (e) = ROTL32(5, a) + Maj(b,c,d) + e + K1_40_TO_59 + ( W1[j&0x0f] = ROTL32(1, T1) ); \
- (b) = ROTL32(30, b); \
- j++;
-
-#define ROUND1_60_TO_79(a,b,c,d,e) \
- T1 = W1[(j+13)&0x0f] ^ W1[(j+8)&0x0f] ^ W1[(j+2)&0x0f] ^ W1[j&0x0f]; \
- (e) = ROTL32(5, a) + Parity(b,c,d) + e + K1_60_TO_79 + ( W1[j&0x0f] = ROTL32(1, T1) ); \
- (b) = ROTL32(30, b); \
- j++;
-
-void SHA1_Internal_Transform(SHA_CTX* context, const sha_word32* data) {
- sha_word32 a, b, c, d, e;
- sha_word32 T1, *W1;
- int j;
-
- W1 = (sha_word32*)context->s1.buffer;
-
- /* Initialize registers with the prev. intermediate value */
- a = context->s1.state[0];
- b = context->s1.state[1];
- c = context->s1.state[2];
- d = context->s1.state[3];
- e = context->s1.state[4];
-
- j = 0;
-
- /* Rounds 0 to 15 unrolled: */
- ROUND1_0_TO_15(a,b,c,d,e);
- ROUND1_0_TO_15(e,a,b,c,d);
- ROUND1_0_TO_15(d,e,a,b,c);
- ROUND1_0_TO_15(c,d,e,a,b);
- ROUND1_0_TO_15(b,c,d,e,a);
- ROUND1_0_TO_15(a,b,c,d,e);
- ROUND1_0_TO_15(e,a,b,c,d);
- ROUND1_0_TO_15(d,e,a,b,c);
- ROUND1_0_TO_15(c,d,e,a,b);
- ROUND1_0_TO_15(b,c,d,e,a);
- ROUND1_0_TO_15(a,b,c,d,e);
- ROUND1_0_TO_15(e,a,b,c,d);
- ROUND1_0_TO_15(d,e,a,b,c);
- ROUND1_0_TO_15(c,d,e,a,b);
- ROUND1_0_TO_15(b,c,d,e,a);
- ROUND1_0_TO_15(a,b,c,d,e);
-
- /* Rounds 16 to 19 unrolled: */
- ROUND1_16_TO_19(e,a,b,c,d);
- ROUND1_16_TO_19(d,e,a,b,c);
- ROUND1_16_TO_19(c,d,e,a,b);
- ROUND1_16_TO_19(b,c,d,e,a);
-
- /* Rounds 20 to 39 unrolled: */
- ROUND1_20_TO_39(a,b,c,d,e);
- ROUND1_20_TO_39(e,a,b,c,d);
- ROUND1_20_TO_39(d,e,a,b,c);
- ROUND1_20_TO_39(c,d,e,a,b);
- ROUND1_20_TO_39(b,c,d,e,a);
- ROUND1_20_TO_39(a,b,c,d,e);
- ROUND1_20_TO_39(e,a,b,c,d);
- ROUND1_20_TO_39(d,e,a,b,c);
- ROUND1_20_TO_39(c,d,e,a,b);
- ROUND1_20_TO_39(b,c,d,e,a);
- ROUND1_20_TO_39(a,b,c,d,e);
- ROUND1_20_TO_39(e,a,b,c,d);
- ROUND1_20_TO_39(d,e,a,b,c);
- ROUND1_20_TO_39(c,d,e,a,b);
- ROUND1_20_TO_39(b,c,d,e,a);
- ROUND1_20_TO_39(a,b,c,d,e);
- ROUND1_20_TO_39(e,a,b,c,d);
- ROUND1_20_TO_39(d,e,a,b,c);
- ROUND1_20_TO_39(c,d,e,a,b);
- ROUND1_20_TO_39(b,c,d,e,a);
-
- /* Rounds 40 to 59 unrolled: */
- ROUND1_40_TO_59(a,b,c,d,e);
- ROUND1_40_TO_59(e,a,b,c,d);
- ROUND1_40_TO_59(d,e,a,b,c);
- ROUND1_40_TO_59(c,d,e,a,b);
- ROUND1_40_TO_59(b,c,d,e,a);
- ROUND1_40_TO_59(a,b,c,d,e);
- ROUND1_40_TO_59(e,a,b,c,d);
- ROUND1_40_TO_59(d,e,a,b,c);
- ROUND1_40_TO_59(c,d,e,a,b);
- ROUND1_40_TO_59(b,c,d,e,a);
- ROUND1_40_TO_59(a,b,c,d,e);
- ROUND1_40_TO_59(e,a,b,c,d);
- ROUND1_40_TO_59(d,e,a,b,c);
- ROUND1_40_TO_59(c,d,e,a,b);
- ROUND1_40_TO_59(b,c,d,e,a);
- ROUND1_40_TO_59(a,b,c,d,e);
- ROUND1_40_TO_59(e,a,b,c,d);
- ROUND1_40_TO_59(d,e,a,b,c);
- ROUND1_40_TO_59(c,d,e,a,b);
- ROUND1_40_TO_59(b,c,d,e,a);
-
- /* Rounds 60 to 79 unrolled: */
- ROUND1_60_TO_79(a,b,c,d,e);
- ROUND1_60_TO_79(e,a,b,c,d);
- ROUND1_60_TO_79(d,e,a,b,c);
- ROUND1_60_TO_79(c,d,e,a,b);
- ROUND1_60_TO_79(b,c,d,e,a);
- ROUND1_60_TO_79(a,b,c,d,e);
- ROUND1_60_TO_79(e,a,b,c,d);
- ROUND1_60_TO_79(d,e,a,b,c);
- ROUND1_60_TO_79(c,d,e,a,b);
- ROUND1_60_TO_79(b,c,d,e,a);
- ROUND1_60_TO_79(a,b,c,d,e);
- ROUND1_60_TO_79(e,a,b,c,d);
- ROUND1_60_TO_79(d,e,a,b,c);
- ROUND1_60_TO_79(c,d,e,a,b);
- ROUND1_60_TO_79(b,c,d,e,a);
- ROUND1_60_TO_79(a,b,c,d,e);
- ROUND1_60_TO_79(e,a,b,c,d);
- ROUND1_60_TO_79(d,e,a,b,c);
- ROUND1_60_TO_79(c,d,e,a,b);
- ROUND1_60_TO_79(b,c,d,e,a);
-
- /* Compute the current intermediate hash value */
- context->s1.state[0] += a;
- context->s1.state[1] += b;
- context->s1.state[2] += c;
- context->s1.state[3] += d;
- context->s1.state[4] += e;
-
- /* Clean up */
- a = b = c = d = e = T1 = 0;
-}
-
-#else /* SHA2_UNROLL_TRANSFORM */
-
-void SHA1_Internal_Transform(SHA_CTX* context, const sha_word32* data) {
- sha_word32 a, b, c, d, e;
- sha_word32 T1, *W1;
- int j;
-
- W1 = (sha_word32*)context->s1.buffer;
-
- /* Initialize registers with the prev. intermediate value */
- a = context->s1.state[0];
- b = context->s1.state[1];
- c = context->s1.state[2];
- d = context->s1.state[3];
- e = context->s1.state[4];
- j = 0;
- do {
-#if BYTE_ORDER == LITTLE_ENDIAN
- T1 = data[j];
- /* Copy data while converting to host byte order */
- REVERSE32(*data++, W1[j]);
- T1 = ROTL32(5, a) + Ch(b, c, d) + e + K1_0_TO_19 + W1[j];
-#else /* BYTE_ORDER == LITTLE_ENDIAN */
- T1 = ROTL32(5, a) + Ch(b, c, d) + e + K1_0_TO_19 + (W1[j] = *data++);
-#endif /* BYTE_ORDER == LITTLE_ENDIAN */
- e = d;
- d = c;
- c = ROTL32(30, b);
- b = a;
- a = T1;
- j++;
- } while (j < 16);
-
- do {
- T1 = W1[(j+13)&0x0f] ^ W1[(j+8)&0x0f] ^ W1[(j+2)&0x0f] ^ W1[j&0x0f];
- T1 = ROTL32(5, a) + Ch(b,c,d) + e + K1_0_TO_19 + (W1[j&0x0f] = ROTL32(1, T1));
- e = d;
- d = c;
- c = ROTL32(30, b);
- b = a;
- a = T1;
- j++;
- } while (j < 20);
-
- do {
- T1 = W1[(j+13)&0x0f] ^ W1[(j+8)&0x0f] ^ W1[(j+2)&0x0f] ^ W1[j&0x0f];
- T1 = ROTL32(5, a) + Parity(b,c,d) + e + K1_20_TO_39 + (W1[j&0x0f] = ROTL32(1, T1));
- e = d;
- d = c;
- c = ROTL32(30, b);
- b = a;
- a = T1;
- j++;
- } while (j < 40);
-
- do {
- T1 = W1[(j+13)&0x0f] ^ W1[(j+8)&0x0f] ^ W1[(j+2)&0x0f] ^ W1[j&0x0f];
- T1 = ROTL32(5, a) + Maj(b,c,d) + e + K1_40_TO_59 + (W1[j&0x0f] = ROTL32(1, T1));
- e = d;
- d = c;
- c = ROTL32(30, b);
- b = a;
- a = T1;
- j++;
- } while (j < 60);
-
- do {
- T1 = W1[(j+13)&0x0f] ^ W1[(j+8)&0x0f] ^ W1[(j+2)&0x0f] ^ W1[j&0x0f];
- T1 = ROTL32(5, a) + Parity(b,c,d) + e + K1_60_TO_79 + (W1[j&0x0f] = ROTL32(1, T1));
- e = d;
- d = c;
- c = ROTL32(30, b);
- b = a;
- a = T1;
- j++;
- } while (j < 80);
-
-
- /* Compute the current intermediate hash value */
- context->s1.state[0] += a;
- context->s1.state[1] += b;
- context->s1.state[2] += c;
- context->s1.state[3] += d;
- context->s1.state[4] += e;
-
- /* Clean up */
- a = b = c = d = e = T1 = 0;
-}
-
-#endif /* SHA2_UNROLL_TRANSFORM */
-
-void SHA1_Update(SHA_CTX* context, const sha_byte *data, size_t len) {
- unsigned int freespace, usedspace;
- if (len == 0) {
- /* Calling with no data is valid - we do nothing */
- return;
- }
-
- /* Sanity check: */
- assert(context != (SHA_CTX*)0 && data != (sha_byte*)0);
-
- usedspace = (unsigned int)((context->s1.bitcount >> 3) % 64);
- if (usedspace > 0) {
- /* Calculate how much free space is available in the buffer */
- freespace = 64 - usedspace;
-
- if (len >= freespace) {
- /* Fill the buffer completely and process it */
- MEMCPY_BCOPY(&context->s1.buffer[usedspace], data, freespace);
- context->s1.bitcount += freespace << 3;
- len -= freespace;
- data += freespace;
- SHA1_Internal_Transform(context, (const sha_word32*)context->s1.buffer);
- } else {
- /* The buffer is not yet full */
- MEMCPY_BCOPY(&context->s1.buffer[usedspace], data, len);
- context->s1.bitcount += len << 3;
- /* Clean up: */
- usedspace = freespace = 0;
- return;
- }
- }
- while (len >= 64) {
- /* Process as many complete blocks as we can */
- SHA1_Internal_Transform(context, (const sha_word32*)data);
- context->s1.bitcount += 512;
- len -= 64;
- data += 64;
- }
- if (len > 0) {
- /* There's left-overs, so save 'em */
- MEMCPY_BCOPY(context->s1.buffer, data, len);
- context->s1.bitcount += len << 3;
- }
- /* Clean up: */
- usedspace = freespace = 0;
-}
-
-void SHA1_Final(sha_byte digest[], SHA_CTX* context) {
- sha_word32 *d = (sha_word32*)digest;
- unsigned int usedspace;
-
- /* Sanity check: */
- assert(context != (SHA_CTX*)0);
-
- if (digest == (sha_byte*)0) {
- /*
- * No digest buffer, so we can do nothing
- * except clean up and go home
- */
- MEMSET_BZERO(context, sizeof(*context));
- return;
- }
-
- usedspace = (unsigned int)((context->s1.bitcount >> 3) % 64);
- if (usedspace == 0) {
- /* Set-up for the last transform: */
- MEMSET_BZERO(context->s1.buffer, 56);
-
- /* Begin padding with a 1 bit: */
- *context->s1.buffer = 0x80;
- } else {
- /* Begin padding with a 1 bit: */
- context->s1.buffer[usedspace++] = 0x80;
-
- if (usedspace <= 56) {
- /* Set-up for the last transform: */
- MEMSET_BZERO(&context->s1.buffer[usedspace], 56 - usedspace);
- } else {
- if (usedspace < 64) {
- MEMSET_BZERO(&context->s1.buffer[usedspace], 64 - usedspace);
- }
- /* Do second-to-last transform: */
- SHA1_Internal_Transform(context, (const sha_word32*)context->s1.buffer);
-
- /* And set-up for the last transform: */
- MEMSET_BZERO(context->s1.buffer, 56);
- }
- /* Clean up: */
- usedspace = 0;
- }
- /* Set the bit count: */
-#if BYTE_ORDER == LITTLE_ENDIAN
- /* Convert FROM host byte order */
- REVERSE64(context->s1.bitcount,context->s1.bitcount);
-#endif
- MEMCPY_BCOPY(&context->s1.buffer[56], &context->s1.bitcount,
- sizeof(sha_word64));
-
- /* Final transform: */
- SHA1_Internal_Transform(context, (const sha_word32*)context->s1.buffer);
-
- /* Save the hash data for output: */
-#if BYTE_ORDER == LITTLE_ENDIAN
- {
- /* Convert TO host byte order */
- int j;
- for (j = 0; j < (SHA1_DIGEST_LENGTH >> 2); j++) {
- REVERSE32(context->s1.state[j],context->s1.state[j]);
- *d++ = context->s1.state[j];
- }
- }
-#else
- MEMCPY_BCOPY(d, context->s1.state, SHA1_DIGEST_LENGTH);
-#endif
-
- /* Clean up: */
- MEMSET_BZERO(context, sizeof(*context));
-}
-
-char *SHA1_End(SHA_CTX* context, char buffer[]) {
- sha_byte digest[SHA1_DIGEST_LENGTH], *d = digest;
- int i;
-
- /* Sanity check: */
- assert(context != (SHA_CTX*)0);
-
- if (buffer != (char*)0) {
- SHA1_Final(digest, context);
-
- for (i = 0; i < SHA1_DIGEST_LENGTH; i++) {
- *buffer++ = sha_hex_digits[(*d & 0xf0) >> 4];
- *buffer++ = sha_hex_digits[*d & 0x0f];
- d++;
- }
- *buffer = (char)0;
- } else {
- MEMSET_BZERO(context, sizeof(*context));
- }
- MEMSET_BZERO(digest, SHA1_DIGEST_LENGTH);
- return buffer;
-}
-
-char* SHA1_Data(const sha_byte* data, size_t len, char digest[SHA1_DIGEST_STRING_LENGTH]) {
- SHA_CTX context;
-
- SHA1_Init(&context);
- SHA1_Update(&context, data, len);
- return SHA1_End(&context, digest);
-}
-
-
-/*** SHA-256: *********************************************************/
-void SHA256_Internal_Init(SHA_CTX* context, const sha_word32* ihv) {
- /* Sanity check: */
- assert(context != (SHA_CTX*)0);
-
- MEMCPY_BCOPY(context->s256.state, ihv, sizeof(sha_word32) * 8);
- MEMSET_BZERO(context->s256.buffer, 64);
- context->s256.bitcount = 0;
-}
-
-void SHA256_Init(SHA_CTX* context) {
- SHA256_Internal_Init(context, sha256_initial_hash_value);
-}
-
-#ifdef SHA2_UNROLL_TRANSFORM
-
-/* Unrolled SHA-256 round macros: */
-
-#if BYTE_ORDER == LITTLE_ENDIAN
-
-#define ROUND256_0_TO_15(a,b,c,d,e,f,g,h) \
- REVERSE32(*data++, W256[j]); \
- T1 = (h) + Sigma1_256(e) + Ch((e), (f), (g)) + \
- K256[j] + W256[j]; \
- (d) += T1; \
- (h) = T1 + Sigma0_256(a) + Maj((a), (b), (c)); \
- j++
-
-
-#else /* BYTE_ORDER == LITTLE_ENDIAN */
-
-#define ROUND256_0_TO_15(a,b,c,d,e,f,g,h) \
- T1 = (h) + Sigma1_256(e) + Ch((e), (f), (g)) + \
- K256[j] + (W256[j] = *data++); \
- (d) += T1; \
- (h) = T1 + Sigma0_256(a) + Maj((a), (b), (c)); \
- j++
-
-#endif /* BYTE_ORDER == LITTLE_ENDIAN */
-
-#define ROUND256(a,b,c,d,e,f,g,h) \
- s0 = W256[(j+1)&0x0f]; \
- s0 = sigma0_256(s0); \
- s1 = W256[(j+14)&0x0f]; \
- s1 = sigma1_256(s1); \
- T1 = (h) + Sigma1_256(e) + Ch((e), (f), (g)) + K256[j] + \
- (W256[j&0x0f] += s1 + W256[(j+9)&0x0f] + s0); \
- (d) += T1; \
- (h) = T1 + Sigma0_256(a) + Maj((a), (b), (c)); \
- j++
-
-void SHA256_Internal_Transform(SHA_CTX* context, const sha_word32* data) {
- sha_word32 a, b, c, d, e, f, g, h, s0, s1;
- sha_word32 T1, *W256;
- int j;
-
- W256 = (sha_word32*)context->s256.buffer;
-
- /* Initialize registers with the prev. intermediate value */
- a = context->s256.state[0];
- b = context->s256.state[1];
- c = context->s256.state[2];
- d = context->s256.state[3];
- e = context->s256.state[4];
- f = context->s256.state[5];
- g = context->s256.state[6];
- h = context->s256.state[7];
-
- j = 0;
- do {
- /* Rounds 0 to 15 (unrolled): */
- ROUND256_0_TO_15(a,b,c,d,e,f,g,h);
- ROUND256_0_TO_15(h,a,b,c,d,e,f,g);
- ROUND256_0_TO_15(g,h,a,b,c,d,e,f);
- ROUND256_0_TO_15(f,g,h,a,b,c,d,e);
- ROUND256_0_TO_15(e,f,g,h,a,b,c,d);
- ROUND256_0_TO_15(d,e,f,g,h,a,b,c);
- ROUND256_0_TO_15(c,d,e,f,g,h,a,b);
- ROUND256_0_TO_15(b,c,d,e,f,g,h,a);
- } while (j < 16);
-
- /* Now for the remaining rounds to 64: */
- do {
- ROUND256(a,b,c,d,e,f,g,h);
- ROUND256(h,a,b,c,d,e,f,g);
- ROUND256(g,h,a,b,c,d,e,f);
- ROUND256(f,g,h,a,b,c,d,e);
- ROUND256(e,f,g,h,a,b,c,d);
- ROUND256(d,e,f,g,h,a,b,c);
- ROUND256(c,d,e,f,g,h,a,b);
- ROUND256(b,c,d,e,f,g,h,a);
- } while (j < 64);
-
- /* Compute the current intermediate hash value */
- context->s256.state[0] += a;
- context->s256.state[1] += b;
- context->s256.state[2] += c;
- context->s256.state[3] += d;
- context->s256.state[4] += e;
- context->s256.state[5] += f;
- context->s256.state[6] += g;
- context->s256.state[7] += h;
-
- /* Clean up */
- a = b = c = d = e = f = g = h = T1 = 0;
-}
-
-#else /* SHA2_UNROLL_TRANSFORM */
-
-void SHA256_Internal_Transform(SHA_CTX* context, const sha_word32* data) {
- sha_word32 a, b, c, d, e, f, g, h, s0, s1;
- sha_word32 T1, T2, *W256;
- int j;
-
- W256 = (sha_word32*)context->s256.buffer;
-
- /* Initialize registers with the prev. intermediate value */
- a = context->s256.state[0];
- b = context->s256.state[1];
- c = context->s256.state[2];
- d = context->s256.state[3];
- e = context->s256.state[4];
- f = context->s256.state[5];
- g = context->s256.state[6];
- h = context->s256.state[7];
-
- j = 0;
- do {
-#if BYTE_ORDER == LITTLE_ENDIAN
- /* Copy data while converting to host byte order */
- REVERSE32(*data++,W256[j]);
- /* Apply the SHA-256 compression function to update a..h */
- T1 = h + Sigma1_256(e) + Ch(e, f, g) + K256[j] + W256[j];
-#else /* BYTE_ORDER == LITTLE_ENDIAN */
- /* Apply the SHA-256 compression function to update a..h with copy */
- T1 = h + Sigma1_256(e) + Ch(e, f, g) + K256[j] + (W256[j] = *data++);
-#endif /* BYTE_ORDER == LITTLE_ENDIAN */
- T2 = Sigma0_256(a) + Maj(a, b, c);
- h = g;
- g = f;
- f = e;
- e = d + T1;
- d = c;
- c = b;
- b = a;
- a = T1 + T2;
-
- j++;
- } while (j < 16);
-
- do {
- /* Part of the message block expansion: */
- s0 = W256[(j+1)&0x0f];
- s0 = sigma0_256(s0);
- s1 = W256[(j+14)&0x0f];
- s1 = sigma1_256(s1);
-
- /* Apply the SHA-256 compression function to update a..h */
- T1 = h + Sigma1_256(e) + Ch(e, f, g) + K256[j] +
- (W256[j&0x0f] += s1 + W256[(j+9)&0x0f] + s0);
- T2 = Sigma0_256(a) + Maj(a, b, c);
- h = g;
- g = f;
- f = e;
- e = d + T1;
- d = c;
- c = b;
- b = a;
- a = T1 + T2;
-
- j++;
- } while (j < 64);
-
- /* Compute the current intermediate hash value */
- context->s256.state[0] += a;
- context->s256.state[1] += b;
- context->s256.state[2] += c;
- context->s256.state[3] += d;
- context->s256.state[4] += e;
- context->s256.state[5] += f;
- context->s256.state[6] += g;
- context->s256.state[7] += h;
-
- /* Clean up */
- a = b = c = d = e = f = g = h = T1 = T2 = 0;
-}
-
-#endif /* SHA2_UNROLL_TRANSFORM */
-
-void SHA256_Update(SHA_CTX* context, const sha_byte *data, size_t len) {
- unsigned int freespace, usedspace;
-
- if (len == 0) {
- /* Calling with no data is valid - we do nothing */
- return;
- }
-
- /* Sanity check: */
- assert(context != (SHA_CTX*)0 && data != (sha_byte*)0);
-
- usedspace = (unsigned int)((context->s256.bitcount >> 3) % 64);
- if (usedspace > 0) {
- /* Calculate how much free space is available in the buffer */
- freespace = 64 - usedspace;
-
- if (len >= freespace) {
- /* Fill the buffer completely and process it */
- MEMCPY_BCOPY(&context->s256.buffer[usedspace], data, freespace);
- context->s256.bitcount += freespace << 3;
- len -= freespace;
- data += freespace;
- SHA256_Internal_Transform(context, (const sha_word32*)context->s256.buffer);
- } else {
- /* The buffer is not yet full */
- MEMCPY_BCOPY(&context->s256.buffer[usedspace], data, len);
- context->s256.bitcount += len << 3;
- /* Clean up: */
- usedspace = freespace = 0;
- return;
- }
- }
- while (len >= 64) {
- /* Process as many complete blocks as we can */
- SHA256_Internal_Transform(context, (const sha_word32*)data);
- context->s256.bitcount += 512;
- len -= 64;
- data += 64;
- }
- if (len > 0) {
- /* There's left-overs, so save 'em */
- MEMCPY_BCOPY(context->s256.buffer, data, len);
- context->s256.bitcount += len << 3;
- }
- /* Clean up: */
- usedspace = freespace = 0;
-}
-
-void SHA256_Internal_Last(SHA_CTX* context) {
- unsigned int usedspace;
-
- usedspace = (unsigned int)((context->s256.bitcount >> 3) % 64);
-#if BYTE_ORDER == LITTLE_ENDIAN
- /* Convert FROM host byte order */
- REVERSE64(context->s256.bitcount,context->s256.bitcount);
-#endif
- if (usedspace > 0) {
- /* Begin padding with a 1 bit: */
- context->s256.buffer[usedspace++] = 0x80;
-
- if (usedspace <= 56) {
- /* Set-up for the last transform: */
- MEMSET_BZERO(&context->s256.buffer[usedspace], 56 - usedspace);
- } else {
- if (usedspace < 64) {
- MEMSET_BZERO(&context->s256.buffer[usedspace], 64 - usedspace);
- }
- /* Do second-to-last transform: */
- SHA256_Internal_Transform(context, (const sha_word32*)context->s256.buffer);
-
- /* And set-up for the last transform: */
- MEMSET_BZERO(context->s256.buffer, 56);
- }
- /* Clean up: */
- usedspace = 0;
- } else {
- /* Set-up for the last transform: */
- MEMSET_BZERO(context->s256.buffer, 56);
-
- /* Begin padding with a 1 bit: */
- *context->s256.buffer = 0x80;
- }
- /* Set the bit count: */
- MEMCPY_BCOPY(&context->s256.buffer[56], &context->s256.bitcount,
- sizeof(sha_word64));
-
- /* Final transform: */
- SHA256_Internal_Transform(context, (const sha_word32*)context->s256.buffer);
-}
-
-void SHA256_Final(sha_byte digest[], SHA_CTX* context) {
- sha_word32 *d = (sha_word32*)digest;
-
- /* Sanity check: */
- assert(context != (SHA_CTX*)0);
-
- /* If no digest buffer is passed, we don't bother doing this: */
- if (digest != (sha_byte*)0) {
- SHA256_Internal_Last(context);
-
- /* Save the hash data for output: */
-#if BYTE_ORDER == LITTLE_ENDIAN
- {
- /* Convert TO host byte order */
- int j;
- for (j = 0; j < (SHA256_DIGEST_LENGTH >> 2); j++) {
- REVERSE32(context->s256.state[j],context->s256.state[j]);
- *d++ = context->s256.state[j];
- }
- }
-#else
- MEMCPY_BCOPY(d, context->s256.state, SHA256_DIGEST_LENGTH);
-#endif
- }
-
- /* Clean up state data: */
- MEMSET_BZERO(context, sizeof(*context));
-}
-
-char *SHA256_End(SHA_CTX* context, char buffer[]) {
- sha_byte digest[SHA256_DIGEST_LENGTH], *d = digest;
- int i;
-
- /* Sanity check: */
- assert(context != (SHA_CTX*)0);
-
- if (buffer != (char*)0) {
- SHA256_Final(digest, context);
-
- for (i = 0; i < SHA256_DIGEST_LENGTH; i++) {
- *buffer++ = sha_hex_digits[(*d & 0xf0) >> 4];
- *buffer++ = sha_hex_digits[*d & 0x0f];
- d++;
- }
- *buffer = (char)0;
- } else {
- MEMSET_BZERO(context, sizeof(*context));
- }
- MEMSET_BZERO(digest, SHA256_DIGEST_LENGTH);
- return buffer;
-}
-
-char* SHA256_Data(const sha_byte* data, size_t len, char digest[SHA256_DIGEST_STRING_LENGTH]) {
- SHA_CTX context;
-
- SHA256_Init(&context);
- SHA256_Update(&context, data, len);
- return SHA256_End(&context, digest);
-}
-
-
-/*** SHA-224: *********************************************************/
-void SHA224_Init(SHA_CTX* context) {
- SHA256_Internal_Init(context, sha224_initial_hash_value);
-}
-
-void SHA224_Internal_Transform(SHA_CTX* context, const sha_word32* data) {
- SHA256_Internal_Transform(context, data);
-}
-
-void SHA224_Update(SHA_CTX* context, const sha_byte *data, size_t len) {
- SHA256_Update(context, data, len);
-}
-
-void SHA224_Final(sha_byte digest[], SHA_CTX* context) {
- sha_word32 *d = (sha_word32*)digest;
-
- /* Sanity check: */
- assert(context != (SHA_CTX*)0);
-
- /* If no digest buffer is passed, we don't bother doing this: */
- if (digest != (sha_byte*)0) {
- SHA256_Internal_Last(context);
-
- /* Save the hash data for output: */
-#if BYTE_ORDER == LITTLE_ENDIAN
- {
- /* Convert TO host byte order */
- int j;
- for (j = 0; j < (SHA224_DIGEST_LENGTH >> 2); j++) {
- REVERSE32(context->s256.state[j],context->s256.state[j]);
- *d++ = context->s256.state[j];
- }
- }
-#else
- MEMCPY_BCOPY(d, context->s256.state, SHA224_DIGEST_LENGTH);
-#endif
- }
-
- /* Clean up state data: */
- MEMSET_BZERO(context, sizeof(*context));
-}
-
-char *SHA224_End(SHA_CTX* context, char buffer[]) {
- sha_byte digest[SHA224_DIGEST_LENGTH], *d = digest;
- int i;
-
- /* Sanity check: */
- assert(context != (SHA_CTX*)0);
-
- if (buffer != (char*)0) {
- SHA224_Final(digest, context);
-
- for (i = 0; i < SHA224_DIGEST_LENGTH; i++) {
- *buffer++ = sha_hex_digits[(*d & 0xf0) >> 4];
- *buffer++ = sha_hex_digits[*d & 0x0f];
- d++;
- }
- *buffer = (char)0;
- } else {
- MEMSET_BZERO(context, sizeof(*context));
- }
- MEMSET_BZERO(digest, SHA224_DIGEST_LENGTH);
- return buffer;
-}
-
-char* SHA224_Data(const sha_byte* data, size_t len, char digest[SHA224_DIGEST_STRING_LENGTH]) {
- SHA_CTX context;
-
- SHA224_Init(&context);
- SHA224_Update(&context, data, len);
- return SHA224_End(&context, digest);
-}
-
-
-/*** SHA-512: *********************************************************/
-void SHA512_Internal_Init(SHA_CTX* context, const sha_word64* ihv) {
- /* Sanity check: */
- assert(context != (SHA_CTX*)0);
-
- MEMCPY_BCOPY(context->s512.state, ihv, sizeof(sha_word64) * 8);
- MEMSET_BZERO(context->s512.buffer, 128);
- context->s512.bitcount[0] = context->s512.bitcount[1] = 0;
-}
-
-void SHA512_Init(SHA_CTX* context) {
- SHA512_Internal_Init(context, sha512_initial_hash_value);
-}
-
-#ifdef SHA2_UNROLL_TRANSFORM
-
-/* Unrolled SHA-512 round macros: */
-#if BYTE_ORDER == LITTLE_ENDIAN
-
-#define ROUND512_0_TO_15(a,b,c,d,e,f,g,h) \
- REVERSE64(*data++, W512[j]); \
- T1 = (h) + Sigma1_512(e) + Ch((e), (f), (g)) + \
- K512[j] + W512[j]; \
- (d) += T1, \
- (h) = T1 + Sigma0_512(a) + Maj((a), (b), (c)), \
- j++
-
-
-#else /* BYTE_ORDER == LITTLE_ENDIAN */
-
-#define ROUND512_0_TO_15(a,b,c,d,e,f,g,h) \
- T1 = (h) + Sigma1_512(e) + Ch((e), (f), (g)) + \
- K512[j] + (W512[j] = *data++); \
- (d) += T1; \
- (h) = T1 + Sigma0_512(a) + Maj((a), (b), (c)); \
- j++
-
-#endif /* BYTE_ORDER == LITTLE_ENDIAN */
-
-#define ROUND512(a,b,c,d,e,f,g,h) \
- s0 = W512[(j+1)&0x0f]; \
- s0 = sigma0_512(s0); \
- s1 = W512[(j+14)&0x0f]; \
- s1 = sigma1_512(s1); \
- T1 = (h) + Sigma1_512(e) + Ch((e), (f), (g)) + K512[j] + \
- (W512[j&0x0f] += s1 + W512[(j+9)&0x0f] + s0); \
- (d) += T1; \
- (h) = T1 + Sigma0_512(a) + Maj((a), (b), (c)); \
- j++
-
-void SHA512_Internal_Transform(SHA_CTX* context, const sha_word64* data) {
- sha_word64 a, b, c, d, e, f, g, h, s0, s1;
- sha_word64 T1, *W512 = (sha_word64*)context->s512.buffer;
- int j;
-
- /* Initialize registers with the prev. intermediate value */
- a = context->s512.state[0];
- b = context->s512.state[1];
- c = context->s512.state[2];
- d = context->s512.state[3];
- e = context->s512.state[4];
- f = context->s512.state[5];
- g = context->s512.state[6];
- h = context->s512.state[7];
-
- j = 0;
- do {
- ROUND512_0_TO_15(a,b,c,d,e,f,g,h);
- ROUND512_0_TO_15(h,a,b,c,d,e,f,g);
- ROUND512_0_TO_15(g,h,a,b,c,d,e,f);
- ROUND512_0_TO_15(f,g,h,a,b,c,d,e);
- ROUND512_0_TO_15(e,f,g,h,a,b,c,d);
- ROUND512_0_TO_15(d,e,f,g,h,a,b,c);
- ROUND512_0_TO_15(c,d,e,f,g,h,a,b);
- ROUND512_0_TO_15(b,c,d,e,f,g,h,a);
- } while (j < 16);
-
- /* Now for the remaining rounds up to 79: */
- do {
- ROUND512(a,b,c,d,e,f,g,h);
- ROUND512(h,a,b,c,d,e,f,g);
- ROUND512(g,h,a,b,c,d,e,f);
- ROUND512(f,g,h,a,b,c,d,e);
- ROUND512(e,f,g,h,a,b,c,d);
- ROUND512(d,e,f,g,h,a,b,c);
- ROUND512(c,d,e,f,g,h,a,b);
- ROUND512(b,c,d,e,f,g,h,a);
- } while (j < 80);
-
- /* Compute the current intermediate hash value */
- context->s512.state[0] += a;
- context->s512.state[1] += b;
- context->s512.state[2] += c;
- context->s512.state[3] += d;
- context->s512.state[4] += e;
- context->s512.state[5] += f;
- context->s512.state[6] += g;
- context->s512.state[7] += h;
-
- /* Clean up */
- a = b = c = d = e = f = g = h = T1 = 0;
-}
-
-#else /* SHA2_UNROLL_TRANSFORM */
-
-void SHA512_Internal_Transform(SHA_CTX* context, const sha_word64* data) {
- sha_word64 a, b, c, d, e, f, g, h, s0, s1;
- sha_word64 T1, T2, *W512 = (sha_word64*)context->s512.buffer;
- int j;
-
- /* Initialize registers with the prev. intermediate value */
- a = context->s512.state[0];
- b = context->s512.state[1];
- c = context->s512.state[2];
- d = context->s512.state[3];
- e = context->s512.state[4];
- f = context->s512.state[5];
- g = context->s512.state[6];
- h = context->s512.state[7];
-
- j = 0;
- do {
-#if BYTE_ORDER == LITTLE_ENDIAN
- /* Convert TO host byte order */
- REVERSE64(*data++, W512[j]);
- /* Apply the SHA-512 compression function to update a..h */
- T1 = h + Sigma1_512(e) + Ch(e, f, g) + K512[j] + W512[j];
-#else /* BYTE_ORDER == LITTLE_ENDIAN */
- /* Apply the SHA-512 compression function to update a..h with copy */
- T1 = h + Sigma1_512(e) + Ch(e, f, g) + K512[j] + (W512[j] = *data++);
-#endif /* BYTE_ORDER == LITTLE_ENDIAN */
- T2 = Sigma0_512(a) + Maj(a, b, c);
- h = g;
- g = f;
- f = e;
- e = d + T1;
- d = c;
- c = b;
- b = a;
- a = T1 + T2;
-
- j++;
- } while (j < 16);
-
- do {
- /* Part of the message block expansion: */
- s0 = W512[(j+1)&0x0f];
- s0 = sigma0_512(s0);
- s1 = W512[(j+14)&0x0f];
- s1 = sigma1_512(s1);
-
- /* Apply the SHA-512 compression function to update a..h */
- T1 = h + Sigma1_512(e) + Ch(e, f, g) + K512[j] +
- (W512[j&0x0f] += s1 + W512[(j+9)&0x0f] + s0);
- T2 = Sigma0_512(a) + Maj(a, b, c);
- h = g;
- g = f;
- f = e;
- e = d + T1;
- d = c;
- c = b;
- b = a;
- a = T1 + T2;
-
- j++;
- } while (j < 80);
-
- /* Compute the current intermediate hash value */
- context->s512.state[0] += a;
- context->s512.state[1] += b;
- context->s512.state[2] += c;
- context->s512.state[3] += d;
- context->s512.state[4] += e;
- context->s512.state[5] += f;
- context->s512.state[6] += g;
- context->s512.state[7] += h;
-
- /* Clean up */
- a = b = c = d = e = f = g = h = T1 = T2 = 0;
-}
-
-#endif /* SHA2_UNROLL_TRANSFORM */
-
-void SHA512_Update(SHA_CTX* context, const sha_byte *data, size_t len) {
- unsigned int freespace, usedspace;
-
- if (len == 0) {
- /* Calling with no data is valid - we do nothing */
- return;
- }
-
- /* Sanity check: */
- assert(context != (SHA_CTX*)0 && data != (sha_byte*)0);
-
- usedspace = (unsigned int)((context->s512.bitcount[0] >> 3) % 128);
- if (usedspace > 0) {
- /* Calculate how much free space is available in the buffer */
- freespace = 128 - usedspace;
-
- if (len >= freespace) {
- /* Fill the buffer completely and process it */
- MEMCPY_BCOPY(&context->s512.buffer[usedspace], data, freespace);
- ADDINC128(context->s512.bitcount, freespace << 3);
- len -= freespace;
- data += freespace;
- SHA512_Internal_Transform(context, (const sha_word64*)context->s512.buffer);
- } else {
- /* The buffer is not yet full */
- MEMCPY_BCOPY(&context->s512.buffer[usedspace], data, len);
- ADDINC128(context->s512.bitcount, len << 3);
- /* Clean up: */
- usedspace = freespace = 0;
- return;
- }
- }
- while (len >= 128) {
- /* Process as many complete blocks as we can */
- SHA512_Internal_Transform(context, (const sha_word64*)data);
- ADDINC128(context->s512.bitcount, 1024);
- len -= 128;
- data += 128;
- }
- if (len > 0) {
- /* There's left-overs, so save 'em */
- MEMCPY_BCOPY(context->s512.buffer, data, len);
- ADDINC128(context->s512.bitcount, len << 3);
- }
- /* Clean up: */
- usedspace = freespace = 0;
-}
-
-void SHA512_Internal_Last(SHA_CTX* context) {
- unsigned int usedspace;
-
- usedspace = (unsigned int)((context->s512.bitcount[0] >> 3) % 128);
-#if BYTE_ORDER == LITTLE_ENDIAN
- /* Convert FROM host byte order */
- REVERSE64(context->s512.bitcount[0],context->s512.bitcount[0]);
- REVERSE64(context->s512.bitcount[1],context->s512.bitcount[1]);
-#endif
- if (usedspace > 0) {
- /* Begin padding with a 1 bit: */
- context->s512.buffer[usedspace++] = 0x80;
-
- if (usedspace <= 112) {
- /* Set-up for the last transform: */
- MEMSET_BZERO(&context->s512.buffer[usedspace], 112 - usedspace);
- } else {
- if (usedspace < 128) {
- MEMSET_BZERO(&context->s512.buffer[usedspace], 128 - usedspace);
- }
- /* Do second-to-last transform: */
- SHA512_Internal_Transform(context, (const sha_word64*)context->s512.buffer);
-
- /* And set-up for the last transform: */
- MEMSET_BZERO(context->s512.buffer, 112);
- }
- /* Clean up: */
- usedspace = 0;
- } else {
- /* Prepare for final transform: */
- MEMSET_BZERO(context->s512.buffer, 112);
-
- /* Begin padding with a 1 bit: */
- *context->s512.buffer = 0x80;
- }
- /* Store the length of input data (in bits): */
- MEMCPY_BCOPY(&context->s512.buffer[112], &context->s512.bitcount[1],
- sizeof(sha_word64));
- MEMCPY_BCOPY(&context->s512.buffer[120], &context->s512.bitcount[0],
- sizeof(sha_word64));
-
- /* Final transform: */
- SHA512_Internal_Transform(context, (const sha_word64*)context->s512.buffer);
-}
-
-void SHA512_Final(sha_byte digest[], SHA_CTX* context) {
- sha_word64 *d = (sha_word64*)digest;
-
- /* Sanity check: */
- assert(context != (SHA_CTX*)0);
-
- /* If no digest buffer is passed, we don't bother doing this: */
- if (digest != (sha_byte*)0) {
- SHA512_Internal_Last(context);
-
- /* Save the hash data for output: */
-#if BYTE_ORDER == LITTLE_ENDIAN
- {
- /* Convert TO host byte order */
- int j;
- for (j = 0; j < (SHA512_DIGEST_LENGTH >> 3); j++) {
- REVERSE64(context->s512.state[j],context->s512.state[j]);
- *d++ = context->s512.state[j];
- }
- }
-#else
- MEMCPY_BCOPY(d, context->s512.state, SHA512_DIGEST_LENGTH);
-#endif
- }
-
- /* Zero out state data */
- MEMSET_BZERO(context, sizeof(*context));
-}
-
-char *SHA512_End(SHA_CTX* context, char buffer[]) {
- sha_byte digest[SHA512_DIGEST_LENGTH], *d = digest;
- int i;
-
- /* Sanity check: */
- assert(context != (SHA_CTX*)0);
-
- if (buffer != (char*)0) {
- SHA512_Final(digest, context);
-
- for (i = 0; i < SHA512_DIGEST_LENGTH; i++) {
- *buffer++ = sha_hex_digits[(*d & 0xf0) >> 4];
- *buffer++ = sha_hex_digits[*d & 0x0f];
- d++;
- }
- *buffer = (char)0;
- } else {
- MEMSET_BZERO(context, sizeof(*context));
- }
- MEMSET_BZERO(digest, SHA512_DIGEST_LENGTH);
- return buffer;
-}
-
-char* SHA512_Data(const sha_byte* data, size_t len, char digest[SHA512_DIGEST_STRING_LENGTH]) {
- SHA_CTX context;
-
- SHA512_Init(&context);
- SHA512_Update(&context, data, len);
- return SHA512_End(&context, digest);
-}
-
-
-/*** SHA-384: *********************************************************/
-void SHA384_Init(SHA_CTX* context) {
- SHA512_Internal_Init(context, sha384_initial_hash_value);
-}
-
-void SHA384_Update(SHA_CTX* context, const sha_byte* data, size_t len) {
- SHA512_Update(context, data, len);
-}
-
-void SHA384_Final(sha_byte digest[], SHA_CTX* context) {
- sha_word64 *d = (sha_word64*)digest;
-
- /* Sanity check: */
- assert(context != (SHA_CTX*)0);
-
- /* If no digest buffer is passed, we don't bother doing this: */
- if (digest != (sha_byte*)0) {
- SHA512_Internal_Last(context);
-
- /* Save the hash data for output: */
-#if BYTE_ORDER == LITTLE_ENDIAN
- {
- /* Convert TO host byte order */
- int j;
- for (j = 0; j < (SHA384_DIGEST_LENGTH >> 3); j++) {
- REVERSE64(context->s512.state[j],context->s512.state[j]);
- *d++ = context->s512.state[j];
- }
- }
-#else
- MEMCPY_BCOPY(d, context->s512.state, SHA384_DIGEST_LENGTH);
-#endif
- }
-
- /* Zero out state data */
- MEMSET_BZERO(context, sizeof(*context));
-}
-
-char *SHA384_End(SHA_CTX* context, char buffer[]) {
- sha_byte digest[SHA384_DIGEST_LENGTH], *d = digest;
- int i;
-
- /* Sanity check: */
- assert(context != (SHA_CTX*)0);
-
- if (buffer != (char*)0) {
- SHA384_Final(digest, context);
-
- for (i = 0; i < SHA384_DIGEST_LENGTH; i++) {
- *buffer++ = sha_hex_digits[(*d & 0xf0) >> 4];
- *buffer++ = sha_hex_digits[*d & 0x0f];
- d++;
- }
- *buffer = (char)0;
- } else {
- MEMSET_BZERO(context, sizeof(*context));
- }
- MEMSET_BZERO(digest, SHA384_DIGEST_LENGTH);
- return buffer;
-}
-
-char* SHA384_Data(const sha_byte* data, size_t len, char digest[SHA384_DIGEST_STRING_LENGTH]) {
- SHA_CTX context;
-
- SHA384_Init(&context);
- SHA384_Update(&context, data, len);
- return SHA384_End(&context, digest);
-}
diff --git a/Source/cm_sha2.h b/Source/cm_sha2.h
deleted file mode 100644
index f151031..0000000
--- a/Source/cm_sha2.h
+++ /dev/null
@@ -1,140 +0,0 @@
-/*
- * FILE: sha2.h
- * AUTHOR: Aaron D. Gifford
- * http://www.aarongifford.com/computers/sha.html
- *
- * Copyright (c) 2000-2003, Aaron D. Gifford
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the copyright holder nor the names of contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTOR(S) ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTOR(S) BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $Id: sha2.h,v 1.4 2004/01/07 19:06:18 adg Exp $
- */
-
-#ifndef __SHA2_H__
-#define __SHA2_H__
-
-#include "cm_sha2_mangle.h"
-
-/* CMake modification: use integer types from KWIML. */
-#include <cm_kwiml.h>
-typedef KWIML_INT_uint8_t cm_sha2_uint8_t;
-typedef KWIML_INT_uint32_t cm_sha2_uint32_t;
-typedef KWIML_INT_uint64_t cm_sha2_uint64_t;
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-
-/*
- * Import u_intXX_t size_t type definitions from system headers. You
- * may need to change this, or define these things yourself in this
- * file.
- */
-#include <sys/types.h>
-
-/*** SHA-224/256/384/512 Various Length Definitions *******************/
-
-/* Digest lengths for SHA-1/224/256/384/512 */
-#define SHA1_DIGEST_LENGTH 20
-#define SHA1_DIGEST_STRING_LENGTH (SHA1_DIGEST_LENGTH * 2 + 1)
-#define SHA224_DIGEST_LENGTH 28
-#define SHA224_DIGEST_STRING_LENGTH (SHA224_DIGEST_LENGTH * 2 + 1)
-#define SHA256_DIGEST_LENGTH 32
-#define SHA256_DIGEST_STRING_LENGTH (SHA256_DIGEST_LENGTH * 2 + 1)
-#define SHA384_DIGEST_LENGTH 48
-#define SHA384_DIGEST_STRING_LENGTH (SHA384_DIGEST_LENGTH * 2 + 1)
-#define SHA512_DIGEST_LENGTH 64
-#define SHA512_DIGEST_STRING_LENGTH (SHA512_DIGEST_LENGTH * 2 + 1)
-
-
-/*** SHA-224/256/384/512 Context Structures ***************************/
-
-typedef union _SHA_CTX {
- /* SHA-1 uses this part of the union: */
- struct {
- cm_sha2_uint32_t state[5];
- cm_sha2_uint64_t bitcount;
- cm_sha2_uint8_t buffer[64];
- } s1;
-
- /* SHA-224 and SHA-256 use this part of the union: */
- struct {
- cm_sha2_uint32_t state[8];
- cm_sha2_uint64_t bitcount;
- cm_sha2_uint8_t buffer[64];
- } s256;
-
- /* SHA-384 and SHA-512 use this part of the union: */
- struct {
- cm_sha2_uint64_t state[8];
- cm_sha2_uint64_t bitcount[2];
- cm_sha2_uint8_t buffer[128];
- } s512;
-} SHA_CTX;
-
-/*** SHA-256/384/512 Function Prototypes ******************************/
-
-void SHA1_Init(SHA_CTX*);
-void SHA1_Update(SHA_CTX*, const cm_sha2_uint8_t*, size_t);
-void SHA1_Final(cm_sha2_uint8_t[SHA1_DIGEST_LENGTH], SHA_CTX*);
-char* SHA1_End(SHA_CTX*, char[SHA1_DIGEST_STRING_LENGTH]);
-char* SHA1_Data(const cm_sha2_uint8_t*, size_t,
- char[SHA1_DIGEST_STRING_LENGTH]);
-
-void SHA224_Init(SHA_CTX*);
-void SHA224_Update(SHA_CTX*, const cm_sha2_uint8_t*, size_t);
-void SHA224_Final(cm_sha2_uint8_t[SHA224_DIGEST_LENGTH], SHA_CTX*);
-char* SHA224_End(SHA_CTX*, char[SHA224_DIGEST_STRING_LENGTH]);
-char* SHA224_Data(const cm_sha2_uint8_t*, size_t,
- char[SHA224_DIGEST_STRING_LENGTH]);
-
-void SHA256_Init(SHA_CTX*);
-void SHA256_Update(SHA_CTX*, const cm_sha2_uint8_t*, size_t);
-void SHA256_Final(cm_sha2_uint8_t[SHA256_DIGEST_LENGTH], SHA_CTX*);
-char* SHA256_End(SHA_CTX*, char[SHA256_DIGEST_STRING_LENGTH]);
-char* SHA256_Data(const cm_sha2_uint8_t*, size_t,
- char[SHA256_DIGEST_STRING_LENGTH]);
-
-void SHA384_Init(SHA_CTX*);
-void SHA384_Update(SHA_CTX*, const cm_sha2_uint8_t*, size_t);
-void SHA384_Final(cm_sha2_uint8_t[SHA384_DIGEST_LENGTH], SHA_CTX*);
-char* SHA384_End(SHA_CTX*, char[SHA384_DIGEST_STRING_LENGTH]);
-char* SHA384_Data(const cm_sha2_uint8_t*, size_t,
- char[SHA384_DIGEST_STRING_LENGTH]);
-
-void SHA512_Init(SHA_CTX*);
-void SHA512_Update(SHA_CTX*, const cm_sha2_uint8_t*, size_t);
-void SHA512_Final(cm_sha2_uint8_t[SHA512_DIGEST_LENGTH], SHA_CTX*);
-char* SHA512_End(SHA_CTX*, char[SHA512_DIGEST_STRING_LENGTH]);
-char* SHA512_Data(const cm_sha2_uint8_t*, size_t,
- char[SHA512_DIGEST_STRING_LENGTH]);
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-
-#endif /* __SHA2_H__ */
diff --git a/Source/cm_sha2_mangle.h b/Source/cm_sha2_mangle.h
deleted file mode 100644
index 3dce819..0000000
--- a/Source/cm_sha2_mangle.h
+++ /dev/null
@@ -1,42 +0,0 @@
-/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
- file Copyright.txt or https://cmake.org/licensing for details. */
-#ifndef cm_sha2_mangle_h
-#define cm_sha2_mangle_h
-
-/* Mangle sha2 symbol names to avoid possible conflict with
- implementations in other libraries to which CMake links. */
-#define SHA1_Data cmSHA1_Data
-#define SHA1_End cmSHA1_End
-#define SHA1_Final cmSHA1_Final
-#define SHA1_Init cmSHA1_Init
-#define SHA1_Internal_Transform cmSHA1_Internal_Transform
-#define SHA1_Update cmSHA1_Update
-#define SHA224_Data cmSHA224_Data
-#define SHA224_End cmSHA224_End
-#define SHA224_Final cmSHA224_Final
-#define SHA224_Init cmSHA224_Init
-#define SHA224_Internal_Transform cmSHA224_Internal_Transform
-#define SHA224_Update cmSHA224_Update
-#define SHA256_Data cmSHA256_Data
-#define SHA256_End cmSHA256_End
-#define SHA256_Final cmSHA256_Final
-#define SHA256_Init cmSHA256_Init
-#define SHA256_Internal_Init cmSHA256_Internal_Init
-#define SHA256_Internal_Last cmSHA256_Internal_Last
-#define SHA256_Internal_Transform cmSHA256_Internal_Transform
-#define SHA256_Update cmSHA256_Update
-#define SHA384_Data cmSHA384_Data
-#define SHA384_End cmSHA384_End
-#define SHA384_Final cmSHA384_Final
-#define SHA384_Init cmSHA384_Init
-#define SHA384_Update cmSHA384_Update
-#define SHA512_Data cmSHA512_Data
-#define SHA512_End cmSHA512_End
-#define SHA512_Final cmSHA512_Final
-#define SHA512_Init cmSHA512_Init
-#define SHA512_Internal_Init cmSHA512_Internal_Init
-#define SHA512_Internal_Last cmSHA512_Internal_Last
-#define SHA512_Internal_Transform cmSHA512_Internal_Transform
-#define SHA512_Update cmSHA512_Update
-
-#endif
diff --git a/Tests/CMakeLists.txt b/Tests/CMakeLists.txt
index c0ffa46..e914d00 100644
--- a/Tests/CMakeLists.txt
+++ b/Tests/CMakeLists.txt
@@ -1377,6 +1377,10 @@ ${CMake_BINARY_DIR}/bin/cmake -DDIR=dev -P ${CMake_SOURCE_DIR}/Utilities/Release
add_subdirectory(FindJsonCpp)
endif()
+ if(CMake_TEST_FindLibRHash)
+ add_subdirectory(FindLibRHash)
+ endif()
+
if(CMake_TEST_FindLibUV)
add_subdirectory(FindLibUV)
endif()
diff --git a/Tests/FindLibRHash/CMakeLists.txt b/Tests/FindLibRHash/CMakeLists.txt
new file mode 100644
index 0000000..4d3954d
--- /dev/null
+++ b/Tests/FindLibRHash/CMakeLists.txt
@@ -0,0 +1,10 @@
+add_test(NAME FindLibRHash.Test COMMAND
+ ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
+ --build-and-test
+ "${CMake_SOURCE_DIR}/Tests/FindLibRHash/Test"
+ "${CMake_BINARY_DIR}/Tests/FindLibRHash/Test"
+ ${build_generator_args}
+ --build-project TestFindLibRHash
+ --build-options ${build_options}
+ --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
+ )
diff --git a/Tests/FindLibRHash/Test/CMakeLists.txt b/Tests/FindLibRHash/Test/CMakeLists.txt
new file mode 100644
index 0000000..37e062a
--- /dev/null
+++ b/Tests/FindLibRHash/Test/CMakeLists.txt
@@ -0,0 +1,17 @@
+cmake_minimum_required(VERSION 3.7)
+project(TestFindLibRHash C)
+include(CTest)
+
+# CMake does not actually provide FindLibRHash publicly.
+set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/../../../Source/Modules)
+
+find_package(LibRHash REQUIRED)
+
+add_executable(test_librhash_tgt main.c)
+target_link_libraries(test_librhash_tgt LibRHash::LibRHash)
+add_test(NAME test_librhash_tgt COMMAND test_librhash_tgt)
+
+add_executable(test_librhash_var main.c)
+target_include_directories(test_librhash_var PRIVATE ${LibRHash_INCLUDE_DIRS})
+target_link_libraries(test_librhash_var PRIVATE ${LibRHash_LIBRARIES})
+add_test(NAME test_librhash_var COMMAND test_librhash_var)
diff --git a/Tests/FindLibRHash/Test/main.c b/Tests/FindLibRHash/Test/main.c
new file mode 100644
index 0000000..201dced
--- /dev/null
+++ b/Tests/FindLibRHash/Test/main.c
@@ -0,0 +1,7 @@
+#include <rhash.h>
+
+int main()
+{
+ rhash_library_init();
+ return 0;
+}
diff --git a/Utilities/Scripts/clang-format.bash b/Utilities/Scripts/clang-format.bash
index ad3b3a1..8e07c99 100755
--- a/Utilities/Scripts/clang-format.bash
+++ b/Utilities/Scripts/clang-format.bash
@@ -121,7 +121,7 @@ $git_ls -z -- '*.c' '*.cc' '*.cpp' '*.cxx' '*.h' '*.hh' '*.hpp' '*.hxx' |
egrep -z -v '^Source/cmListFileLexer(\.in\.l|\.c)' |
# Exclude third-party sources.
- egrep -z -v '^Source/(cm_sha2|bindexplib)' |
+ egrep -z -v '^Source/bindexplib' |
egrep -z -v '^Source/(kwsys|CursesDialog/form)/' |
egrep -z -v '^Utilities/(KW|cm).*/' |
diff --git a/Utilities/Scripts/update-librhash.bash b/Utilities/Scripts/update-librhash.bash
new file mode 100755
index 0000000..2f67ea2
--- /dev/null
+++ b/Utilities/Scripts/update-librhash.bash
@@ -0,0 +1,43 @@
+#!/usr/bin/env bash
+
+set -e
+set -x
+shopt -s dotglob
+
+readonly name="librhash"
+readonly ownership="librhash upstream <kwrobot@kitware.com>"
+readonly subtree="Utilities/cmlibrhash"
+readonly repo="https://github.com/rhash/rhash.git"
+readonly tag="master"
+readonly shortlog=false
+readonly paths="
+ COPYING
+ README
+ librhash/algorithms.c
+ librhash/algorithms.h
+ librhash/byte_order.c
+ librhash/byte_order.h
+ librhash/hex.c
+ librhash/hex.h
+ librhash/md5.c
+ librhash/md5.h
+ librhash/rhash.c
+ librhash/rhash.h
+ librhash/sha1.c
+ librhash/sha1.h
+ librhash/sha256.c
+ librhash/sha256.h
+ librhash/sha512.c
+ librhash/sha512.h
+ librhash/ustd.h
+ librhash/util.h
+"
+
+extract_source () {
+ git_archive
+ pushd "${extractdir}/${name}-reduced"
+ echo "* -whitespace" > .gitattributes
+ popd
+}
+
+. "${BASH_SOURCE%/*}/update-third-party.bash"
diff --git a/Utilities/cmThirdParty.h.in b/Utilities/cmThirdParty.h.in
index 210e727..a547f0d 100644
--- a/Utilities/cmThirdParty.h.in
+++ b/Utilities/cmThirdParty.h.in
@@ -13,6 +13,7 @@
#cmakedefine CMAKE_USE_SYSTEM_LIBLZMA
#cmakedefine CMAKE_USE_SYSTEM_FORM
#cmakedefine CMAKE_USE_SYSTEM_JSONCPP
+#cmakedefine CMAKE_USE_SYSTEM_LIBRHASH
#cmakedefine CMAKE_USE_SYSTEM_LIBUV
#cmakedefine CTEST_USE_XMLRPC
diff --git a/Utilities/cm_rhash.h b/Utilities/cm_rhash.h
new file mode 100644
index 0000000..c793627
--- /dev/null
+++ b/Utilities/cm_rhash.h
@@ -0,0 +1,14 @@
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+ file Copyright.txt or https://cmake.org/licensing for details. */
+#ifndef cm_rhash_h
+#define cm_rhash_h
+
+/* Use the LibRHash library configured for CMake. */
+#include "cmThirdParty.h"
+#ifdef CMAKE_USE_SYSTEM_LIBRHASH
+#include <rhash.h>
+#else
+#include <cmlibrhash/librhash/rhash.h>
+#endif
+
+#endif
diff --git a/Utilities/cmlibrhash/.gitattributes b/Utilities/cmlibrhash/.gitattributes
new file mode 100644
index 0000000..562b12e
--- /dev/null
+++ b/Utilities/cmlibrhash/.gitattributes
@@ -0,0 +1 @@
+* -whitespace
diff --git a/Utilities/cmlibrhash/CMakeLists.txt b/Utilities/cmlibrhash/CMakeLists.txt
new file mode 100644
index 0000000..340d946
--- /dev/null
+++ b/Utilities/cmlibrhash/CMakeLists.txt
@@ -0,0 +1,38 @@
+project(librhash C)
+
+# Disable warnings to avoid changing 3rd party code.
+if(CMAKE_C_COMPILER_ID MATCHES
+ "^(GNU|Clang|AppleClang|XL|VisualAge|SunPro|MIPSpro|HP|Intel)$")
+ set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -w")
+elseif(CMAKE_C_COMPILER_ID STREQUAL "PathScale")
+ set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -woffall")
+endif()
+
+set(librhash_sources
+ librhash/algorithms.c
+ librhash/algorithms.h
+ librhash/byte_order.c
+ librhash/byte_order.h
+ librhash/hex.c
+ librhash/hex.h
+ librhash/md5.c
+ librhash/md5.h
+ librhash/rhash.c
+ librhash/rhash.h
+ librhash/sha1.c
+ librhash/sha1.h
+ librhash/sha256.c
+ librhash/sha256.h
+ librhash/sha512.c
+ librhash/sha512.h
+ librhash/ustd.h
+ librhash/util.h
+ )
+
+include_directories(
+ ${KWSYS_HEADER_ROOT}
+ )
+
+add_library(cmlibrhash ${librhash_sources})
+
+install(FILES COPYING README DESTINATION ${CMAKE_DOC_DIR}/cmlibrhash)
diff --git a/Utilities/cmlibrhash/COPYING b/Utilities/cmlibrhash/COPYING
new file mode 100644
index 0000000..bf65ee1
--- /dev/null
+++ b/Utilities/cmlibrhash/COPYING
@@ -0,0 +1,15 @@
+
+ RHash License
+
+Copyright (c) 2005-2014 Aleksey Kravchenko <rhash.admin@gmail.com>
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so.
+
+The Software is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+FOR A PARTICULAR PURPOSE. Use this program at your own risk!
diff --git a/Utilities/cmlibrhash/README b/Utilities/cmlibrhash/README
new file mode 100644
index 0000000..4ea492f
--- /dev/null
+++ b/Utilities/cmlibrhash/README
@@ -0,0 +1,7 @@
+ === Notes on RHash License ===
+
+The RHash program and LibRHash library are distributed under RHash License,
+see the COPYING file for details. In particular, the program, the library
+and source code can be used free of charge under the MIT, BSD, GPL,
+commercial or freeware license without additional restrictions. In the case
+the OSI-approved license is required the MIT license should be used.
diff --git a/Utilities/cmlibrhash/librhash/algorithms.c b/Utilities/cmlibrhash/librhash/algorithms.c
new file mode 100644
index 0000000..56d20b8
--- /dev/null
+++ b/Utilities/cmlibrhash/librhash/algorithms.c
@@ -0,0 +1,220 @@
+/* algorithms.c - the algorithms supported by the rhash library
+ *
+ * Copyright: 2011-2012 Aleksey Kravchenko <rhash.admin@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. Use this program at your own risk!
+ */
+
+#include <stdio.h>
+#include <assert.h>
+
+#include "byte_order.h"
+#include "rhash.h"
+#include "algorithms.h"
+
+/* header files of all supported hash sums */
+#if 0
+#include "aich.h"
+#include "crc32.h"
+#include "ed2k.h"
+#include "edonr.h"
+#include "gost.h"
+#include "has160.h"
+#include "md4.h"
+#endif
+#include "md5.h"
+#if 0
+#include "ripemd-160.h"
+#include "snefru.h"
+#endif
+#include "sha1.h"
+#include "sha256.h"
+#include "sha512.h"
+#if 0
+#include "sha3.h"
+#include "tiger.h"
+#include "tth.h"
+#include "whirlpool.h"
+#endif
+
+#ifdef USE_OPENSSL
+/* note: BTIH and AICH depends on the used SHA1 algorithm */
+# define NEED_OPENSSL_INIT (RHASH_MD4 | RHASH_MD5 | \
+ RHASH_SHA1 | RHASH_SHA224 | RHASH_SHA256 | RHASH_SHA384 | RHASH_SHA512 | \
+ RHASH_BTIH | RHASH_AICH | RHASH_RIPEMD160 | RHASH_WHIRLPOOL)
+#else
+# define NEED_OPENSSL_INIT 0
+#endif /* USE_OPENSSL */
+#ifdef GENERATE_GOST_LOOKUP_TABLE
+# define NEED_GOST_INIT (RHASH_GOST | RHASH_GOST_CRYPTOPRO)
+#else
+# define NEED_GOST_INIT 0
+#endif /* GENERATE_GOST_LOOKUP_TABLE */
+#ifdef GENERATE_CRC32_TABLE
+# define NEED_CRC32_INIT RHASH_CRC32
+#else
+# define NEED_CRC32_INIT 0
+#endif /* GENERATE_CRC32_TABLE */
+
+#define RHASH_NEED_INIT_ALG (NEED_CRC32_INIT | NEED_GOST_INIT | NEED_OPENSSL_INIT)
+unsigned rhash_uninitialized_algorithms = RHASH_NEED_INIT_ALG;
+
+rhash_hash_info* rhash_info_table = rhash_hash_info_default;
+int rhash_info_size = RHASH_HASH_COUNT;
+
+#if 0
+static void rhash_crc32_init(uint32_t* crc32);
+static void rhash_crc32_update(uint32_t* crc32, const unsigned char* msg, size_t size);
+static void rhash_crc32_final(uint32_t* crc32, unsigned char* result);
+#endif
+
+#if 0
+rhash_info info_crc32 = { RHASH_CRC32, F_BE32, 4, "CRC32", "crc32" };
+rhash_info info_md4 = { RHASH_MD4, F_LE32, 16, "MD4", "md4" };
+#endif
+rhash_info info_md5 = { RHASH_MD5, F_LE32, 16, "MD5", "md5" };
+rhash_info info_sha1 = { RHASH_SHA1, F_BE32, 20, "SHA1", "sha1" };
+#if 0
+rhash_info info_tiger = { RHASH_TIGER, F_LE64, 24, "TIGER", "tiger" };
+rhash_info info_tth = { RHASH_TTH, F_BS32, 24, "TTH", "tree:tiger" };
+rhash_info info_btih = { RHASH_BTIH, 0, 20, "BTIH", "btih" };
+rhash_info info_ed2k = { RHASH_ED2K, F_LE32, 16, "ED2K", "ed2k" };
+rhash_info info_aich = { RHASH_AICH, F_BS32, 20, "AICH", "aich" };
+rhash_info info_whirlpool = { RHASH_WHIRLPOOL, F_BE64, 64, "WHIRLPOOL", "whirlpool" };
+rhash_info info_rmd160 = { RHASH_RIPEMD160, F_LE32, 20, "RIPEMD-160", "ripemd160" };
+rhash_info info_gost = { RHASH_GOST, F_LE32, 32, "GOST", "gost" };
+rhash_info info_gostpro = { RHASH_GOST_CRYPTOPRO, F_LE32, 32, "GOST-CRYPTOPRO", "gost-cryptopro" };
+rhash_info info_has160 = { RHASH_HAS160, F_LE32, 20, "HAS-160", "has160" };
+rhash_info info_snf128 = { RHASH_SNEFRU128, F_BE32, 16, "SNEFRU-128", "snefru128" };
+rhash_info info_snf256 = { RHASH_SNEFRU256, F_BE32, 32, "SNEFRU-256", "snefru256" };
+#endif
+rhash_info info_sha224 = { RHASH_SHA224, F_BE32, 28, "SHA-224", "sha224" };
+rhash_info info_sha256 = { RHASH_SHA256, F_BE32, 32, "SHA-256", "sha256" };
+rhash_info info_sha384 = { RHASH_SHA384, F_BE64, 48, "SHA-384", "sha384" };
+rhash_info info_sha512 = { RHASH_SHA512, F_BE64, 64, "SHA-512", "sha512" };
+#if 0
+rhash_info info_edr256 = { RHASH_EDONR256, F_LE32, 32, "EDON-R256", "edon-r256" };
+rhash_info info_edr512 = { RHASH_EDONR512, F_LE64, 64, "EDON-R512", "edon-r512" };
+rhash_info info_sha3_224 = { RHASH_SHA3_224, F_LE64, 28, "SHA3-224", "sha3-224" };
+rhash_info info_sha3_256 = { RHASH_SHA3_256, F_LE64, 32, "SHA3-256", "sha3-256" };
+rhash_info info_sha3_384 = { RHASH_SHA3_384, F_LE64, 48, "SHA3-384", "sha3-384" };
+rhash_info info_sha3_512 = { RHASH_SHA3_512, F_LE64, 64, "SHA3-512", "sha3-512" };
+#endif
+
+/* some helper macros */
+#define dgshft(name) (((char*)&((name##_ctx*)0)->hash) - (char*)0)
+#define dgshft2(name, field) (((char*)&((name##_ctx*)0)->field) - (char*)0)
+#define ini(name) ((pinit_t)(name##_init))
+#define upd(name) ((pupdate_t)(name##_update))
+#define fin(name) ((pfinal_t)(name##_final))
+#define iuf(name) ini(name), upd(name), fin(name)
+#define diuf(name) dgshft(name), ini(name), upd(name), fin(name)
+
+/* information about all hashes */
+rhash_hash_info rhash_hash_info_default[RHASH_HASH_COUNT] =
+{
+#if 0
+ { &info_crc32, sizeof(uint32_t), 0, iuf(rhash_crc32), 0 }, /* 32 bit */
+ { &info_md4, sizeof(md4_ctx), dgshft(md4), iuf(rhash_md4), 0 }, /* 128 bit */
+#endif
+ { &info_md5, sizeof(md5_ctx), dgshft(md5), iuf(rhash_md5), 0 }, /* 128 bit */
+ { &info_sha1, sizeof(sha1_ctx), dgshft(sha1), iuf(rhash_sha1), 0 }, /* 160 bit */
+#if 0
+ { &info_tiger, sizeof(tiger_ctx), dgshft(tiger), iuf(rhash_tiger), 0 }, /* 192 bit */
+ { &info_tth, sizeof(tth_ctx), dgshft2(tth, tiger.hash), iuf(rhash_tth), 0 }, /* 192 bit */
+ { &info_ed2k, sizeof(ed2k_ctx), dgshft2(ed2k, md4_context_inner.hash), iuf(rhash_ed2k), 0 }, /* 128 bit */
+ { &info_aich, sizeof(aich_ctx), dgshft2(aich, sha1_context.hash), iuf(rhash_aich), (pcleanup_t)rhash_aich_cleanup }, /* 160 bit */
+ { &info_whirlpool, sizeof(whirlpool_ctx), dgshft(whirlpool), iuf(rhash_whirlpool), 0 }, /* 512 bit */
+ { &info_rmd160, sizeof(ripemd160_ctx), dgshft(ripemd160), iuf(rhash_ripemd160), 0 }, /* 160 bit */
+ { &info_gost, sizeof(gost_ctx), dgshft(gost), iuf(rhash_gost), 0 }, /* 256 bit */
+ { &info_gostpro, sizeof(gost_ctx), dgshft(gost), ini(rhash_gost_cryptopro), upd(rhash_gost), fin(rhash_gost), 0 }, /* 256 bit */
+ { &info_has160, sizeof(has160_ctx), dgshft(has160), iuf(rhash_has160), 0 }, /* 160 bit */
+ { &info_snf128, sizeof(snefru_ctx), dgshft(snefru), ini(rhash_snefru128), upd(rhash_snefru), fin(rhash_snefru), 0 }, /* 128 bit */
+ { &info_snf256, sizeof(snefru_ctx), dgshft(snefru), ini(rhash_snefru256), upd(rhash_snefru), fin(rhash_snefru), 0 }, /* 256 bit */
+#endif
+ { &info_sha224, sizeof(sha256_ctx), dgshft(sha256), ini(rhash_sha224), upd(rhash_sha256), fin(rhash_sha256), 0 }, /* 224 bit */
+ { &info_sha256, sizeof(sha256_ctx), dgshft(sha256), iuf(rhash_sha256), 0 }, /* 256 bit */
+ { &info_sha384, sizeof(sha512_ctx), dgshft(sha512), ini(rhash_sha384), upd(rhash_sha512), fin(rhash_sha512), 0 }, /* 384 bit */
+ { &info_sha512, sizeof(sha512_ctx), dgshft(sha512), iuf(rhash_sha512), 0 }, /* 512 bit */
+#if 0
+ { &info_edr256, sizeof(edonr_ctx), dgshft2(edonr, u.data256.hash) + 32, iuf(rhash_edonr256), 0 }, /* 256 bit */
+ { &info_edr512, sizeof(edonr_ctx), dgshft2(edonr, u.data512.hash) + 64, iuf(rhash_edonr512), 0 }, /* 512 bit */
+ { &info_sha3_224, sizeof(sha3_ctx), dgshft(sha3), ini(rhash_sha3_224), upd(rhash_sha3), fin(rhash_sha3), 0 }, /* 224 bit */
+ { &info_sha3_256, sizeof(sha3_ctx), dgshft(sha3), ini(rhash_sha3_256), upd(rhash_sha3), fin(rhash_sha3), 0 }, /* 256 bit */
+ { &info_sha3_384, sizeof(sha3_ctx), dgshft(sha3), ini(rhash_sha3_384), upd(rhash_sha3), fin(rhash_sha3), 0 }, /* 384 bit */
+ { &info_sha3_512, sizeof(sha3_ctx), dgshft(sha3), ini(rhash_sha3_512), upd(rhash_sha3), fin(rhash_sha3), 0 }, /* 512 bit */
+#endif
+};
+
+/**
+ * Initialize requested algorithms.
+ */
+void rhash_init_algorithms(unsigned mask)
+{
+ (void)mask; /* unused now */
+
+ /* verify that RHASH_HASH_COUNT is the index of the major bit of RHASH_ALL_HASHES */
+ assert(1 == (RHASH_ALL_HASHES >> (RHASH_HASH_COUNT - 1)));
+
+#ifdef GENERATE_CRC32_TABLE
+ rhash_crc32_init_table();
+#endif
+#ifdef GENERATE_GOST_LOOKUP_TABLE
+ rhash_gost_init_table();
+#endif
+ rhash_uninitialized_algorithms = 0;
+}
+
+#if 0
+/* CRC32 helper functions */
+
+/**
+ * Initialize crc32 hash.
+ *
+ * @param crc32 pointer to the hash to initialize
+ */
+static void rhash_crc32_init(uint32_t* crc32)
+{
+ *crc32 = 0; /* note: context size is sizeof(uint32_t) */
+}
+
+/**
+ * Calculate message CRC32 hash.
+ * Can be called repeatedly with chunks of the message to be hashed.
+ *
+ * @param crc32 pointer to the hash
+ * @param msg message chunk
+ * @param size length of the message chunk
+ */
+static void rhash_crc32_update(uint32_t* crc32, const unsigned char* msg, size_t size)
+{
+ *crc32 = rhash_get_crc32(*crc32, msg, size);
+}
+
+/**
+ * Store calculated hash into the given array.
+ *
+ * @param crc32 pointer to the current hash value
+ * @param result calculated hash in binary form
+ */
+static void rhash_crc32_final(uint32_t* crc32, unsigned char* result)
+{
+#if defined(CPU_IA32) || defined(CPU_X64)
+ /* intel CPUs support assigment with non 32-bit aligned pointers */
+ *(unsigned*)result = be2me_32(*crc32);
+#else
+ /* correct saving BigEndian integer on all archs */
+ result[0] = (unsigned char)(*crc32 >> 24), result[1] = (unsigned char)(*crc32 >> 16);
+ result[2] = (unsigned char)(*crc32 >> 8), result[3] = (unsigned char)(*crc32);
+#endif
+}
+#endif
diff --git a/Utilities/cmlibrhash/librhash/algorithms.h b/Utilities/cmlibrhash/librhash/algorithms.h
new file mode 100644
index 0000000..4db2517
--- /dev/null
+++ b/Utilities/cmlibrhash/librhash/algorithms.h
@@ -0,0 +1,120 @@
+/* algorithms.h - rhash library algorithms */
+#ifndef RHASH_ALGORITHMS_H
+#define RHASH_ALGORITHMS_H
+
+#include <stddef.h> /* for ptrdiff_t */
+#include "rhash.h"
+#include "byte_order.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef RHASH_API
+/* modifier for RHash library functions */
+# define RHASH_API
+#endif
+
+typedef void (*pinit_t)(void*);
+typedef void (*pupdate_t)(void *ctx, const void* msg, size_t size);
+typedef void (*pfinal_t)(void*, unsigned char*);
+typedef void (*pcleanup_t)(void*);
+
+/**
+ * Information about a hash function
+ */
+typedef struct rhash_hash_info
+{
+ rhash_info *info;
+ size_t context_size;
+ ptrdiff_t digest_diff;
+ pinit_t init;
+ pupdate_t update;
+ pfinal_t final;
+ pcleanup_t cleanup;
+} rhash_hash_info;
+
+/**
+ * Information on a hash function and its context
+ */
+typedef struct rhash_vector_item
+{
+ struct rhash_hash_info* hash_info;
+ void *context;
+} rhash_vector_item;
+
+/**
+ * The rhash context containing contexts for several hash functions
+ */
+typedef struct rhash_context_ext
+{
+ struct rhash_context rc;
+ unsigned hash_vector_size; /* number of contained hash sums */
+ unsigned flags;
+ unsigned state;
+ void *callback, *callback_data;
+ void *bt_ctx;
+ rhash_vector_item vector[1]; /* contexts of contained hash sums */
+} rhash_context_ext;
+
+extern rhash_hash_info rhash_hash_info_default[RHASH_HASH_COUNT];
+extern rhash_hash_info* rhash_info_table;
+extern int rhash_info_size;
+extern unsigned rhash_uninitialized_algorithms;
+
+extern rhash_info info_crc32;
+extern rhash_info info_md4;
+extern rhash_info info_md5;
+extern rhash_info info_sha1;
+extern rhash_info info_tiger;
+extern rhash_info info_tth ;
+extern rhash_info info_btih;
+extern rhash_info info_ed2k;
+extern rhash_info info_aich;
+extern rhash_info info_whirlpool;
+extern rhash_info info_rmd160;
+extern rhash_info info_gost;
+extern rhash_info info_gostpro;
+extern rhash_info info_has160;
+extern rhash_info info_snf128;
+extern rhash_info info_snf256;
+extern rhash_info info_sha224;
+extern rhash_info info_sha256;
+extern rhash_info info_sha384;
+extern rhash_info info_sha512;
+extern rhash_info info_sha3_224;
+extern rhash_info info_sha3_256;
+extern rhash_info info_sha3_384;
+extern rhash_info info_sha3_512;
+extern rhash_info info_edr256;
+extern rhash_info info_edr512;
+
+/* rhash_info flags */
+#define F_BS32 1 /* default output in base32 */
+#define F_SWAP32 2 /* Big endian flag */
+#define F_SWAP64 4
+
+/* define endianness flags */
+#ifndef CPU_BIG_ENDIAN
+#define F_LE32 0
+#define F_LE64 0
+#define F_BE32 F_SWAP32
+#define F_BE64 F_SWAP64
+#else
+#define F_LE32 F_SWAP32
+#define F_LE64 F_SWAP64
+#define F_BE32 0
+#define F_BE64 0
+#endif
+
+void rhash_init_algorithms(unsigned mask);
+
+#if defined(OPENSSL_RUNTIME) && !defined(USE_OPENSSL)
+# define USE_OPENSSL
+#endif
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif /* __cplusplus */
+
+#endif /* RHASH_ALGORITHMS_H */
diff --git a/Utilities/cmlibrhash/librhash/byte_order.c b/Utilities/cmlibrhash/librhash/byte_order.c
new file mode 100644
index 0000000..8ce6fc8
--- /dev/null
+++ b/Utilities/cmlibrhash/librhash/byte_order.c
@@ -0,0 +1,150 @@
+/* byte_order.c - byte order related platform dependent routines,
+ *
+ * Copyright: 2008-2012 Aleksey Kravchenko <rhash.admin@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. Use this program at your own risk!
+ */
+#include "byte_order.h"
+
+#if !(__GNUC__ >= 4 || (__GNUC__ ==3 && __GNUC_MINOR__ >= 4)) /* if !GCC or GCC < 4.3 */
+
+# if _MSC_VER >= 1300 && (_M_IX86 || _M_AMD64 || _M_IA64) /* if MSVC++ >= 2002 on x86/x64 */
+# include <intrin.h>
+# pragma intrinsic(_BitScanForward)
+
+/**
+ * Returns index of the trailing bit of x.
+ *
+ * @param x the number to process
+ * @return zero-based index of the trailing bit
+ */
+unsigned rhash_ctz(unsigned x)
+{
+ unsigned long index;
+ unsigned char isNonzero = _BitScanForward(&index, x); /* MSVC intrinsic */
+ return (isNonzero ? (unsigned)index : 0);
+}
+# else /* _MSC_VER >= 1300... */
+
+/**
+ * Returns index of the trailing bit of a 32-bit number.
+ * This is a plain C equivalent for GCC __builtin_ctz() bit scan.
+ *
+ * @param x the number to process
+ * @return zero-based index of the trailing bit
+ */
+unsigned rhash_ctz(unsigned x)
+{
+ /* array for conversion to bit position */
+ static unsigned char bit_pos[32] = {
+ 0, 1, 28, 2, 29, 14, 24, 3, 30, 22, 20, 15, 25, 17, 4, 8,
+ 31, 27, 13, 23, 21, 19, 16, 7, 26, 12, 18, 6, 11, 5, 10, 9
+ };
+
+ /* The De Bruijn bit-scan was devised in 1997, according to Donald Knuth
+ * by Martin Lauter. The constant 0x077CB531UL is a De Bruijn sequence,
+ * which produces a unique pattern of bits into the high 5 bits for each
+ * possible bit position that it is multiplied against.
+ * See http://graphics.stanford.edu/~seander/bithacks.html
+ * and http://chessprogramming.wikispaces.com/BitScan */
+ return (unsigned)bit_pos[((uint32_t)((x & -x) * 0x077CB531U)) >> 27];
+}
+# endif /* _MSC_VER >= 1300... */
+#endif /* !(GCC >= 4.3) */
+
+/**
+ * Copy a memory block with simultaneous exchanging byte order.
+ * The byte order is changed from little-endian 32-bit integers
+ * to big-endian (or vice-versa).
+ *
+ * @param to the pointer where to copy memory block
+ * @param index the index to start writing from
+ * @param from the source block to copy
+ * @param length length of the memory block
+ */
+void rhash_swap_copy_str_to_u32(void* to, int index, const void* from, size_t length)
+{
+ /* if all pointers and length are 32-bits aligned */
+ if ( 0 == (( (int)((char*)to - (char*)0) | ((char*)from - (char*)0) | index | length ) & 3) ) {
+ /* copy memory as 32-bit words */
+ const uint32_t* src = (const uint32_t*)from;
+ const uint32_t* end = (const uint32_t*)((const char*)src + length);
+ uint32_t* dst = (uint32_t*)((char*)to + index);
+ while (src < end) *(dst++) = bswap_32( *(src++) );
+ } else {
+ const char* src = (const char*)from;
+ for (length += index; (size_t)index < length; index++) ((char*)to)[index ^ 3] = *(src++);
+ }
+}
+
+/**
+ * Copy a memory block with changed byte order.
+ * The byte order is changed from little-endian 64-bit integers
+ * to big-endian (or vice-versa).
+ *
+ * @param to the pointer where to copy memory block
+ * @param index the index to start writing from
+ * @param from the source block to copy
+ * @param length length of the memory block
+ */
+void rhash_swap_copy_str_to_u64(void* to, int index, const void* from, size_t length)
+{
+ /* if all pointers and length are 64-bits aligned */
+ if ( 0 == (( (int)((char*)to - (char*)0) | ((char*)from - (char*)0) | index | length ) & 7) ) {
+ /* copy aligned memory block as 64-bit integers */
+ const uint64_t* src = (const uint64_t*)from;
+ const uint64_t* end = (const uint64_t*)((const char*)src + length);
+ uint64_t* dst = (uint64_t*)((char*)to + index);
+ while (src < end) *(dst++) = bswap_64( *(src++) );
+ } else {
+ const char* src = (const char*)from;
+ for (length += index; (size_t)index < length; index++) ((char*)to)[index ^ 7] = *(src++);
+ }
+}
+
+/**
+ * Copy data from a sequence of 64-bit words to a binary string of given length,
+ * while changing byte order.
+ *
+ * @param to the binary string to receive data
+ * @param from the source sequence of 64-bit words
+ * @param length the size in bytes of the data being copied
+ */
+void rhash_swap_copy_u64_to_str(void* to, const void* from, size_t length)
+{
+ /* if all pointers and length are 64-bits aligned */
+ if ( 0 == (( (int)((char*)to - (char*)0) | ((char*)from - (char*)0) | length ) & 7) ) {
+ /* copy aligned memory block as 64-bit integers */
+ const uint64_t* src = (const uint64_t*)from;
+ const uint64_t* end = (const uint64_t*)((const char*)src + length);
+ uint64_t* dst = (uint64_t*)to;
+ while (src < end) *(dst++) = bswap_64( *(src++) );
+ } else {
+ size_t index;
+ char* dst = (char*)to;
+ for (index = 0; index < length; index++) *(dst++) = ((char*)from)[index ^ 7];
+ }
+}
+
+/**
+ * Exchange byte order in the given array of 32-bit integers.
+ *
+ * @param arr the array to process
+ * @param length array length
+ */
+void rhash_u32_mem_swap(unsigned *arr, int length)
+{
+ unsigned* end = arr + length;
+ for (; arr < end; arr++) {
+ *arr = bswap_32(*arr);
+ }
+}
diff --git a/Utilities/cmlibrhash/librhash/byte_order.h b/Utilities/cmlibrhash/librhash/byte_order.h
new file mode 100644
index 0000000..d34a020
--- /dev/null
+++ b/Utilities/cmlibrhash/librhash/byte_order.h
@@ -0,0 +1,156 @@
+/* byte_order.h */
+#ifndef BYTE_ORDER_H
+#define BYTE_ORDER_H
+#include "ustd.h"
+#include <stdlib.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* if x86 compatible cpu */
+#if defined(i386) || defined(__i386__) || defined(__i486__) || \
+ defined(__i586__) || defined(__i686__) || defined(__pentium__) || \
+ defined(__pentiumpro__) || defined(__pentium4__) || \
+ defined(__nocona__) || defined(prescott) || defined(__core2__) || \
+ defined(__k6__) || defined(__k8__) || defined(__athlon__) || \
+ defined(__amd64) || defined(__amd64__) || \
+ defined(__x86_64) || defined(__x86_64__) || defined(_M_IX86) || \
+ defined(_M_AMD64) || defined(_M_IA64) || defined(_M_X64)
+/* detect if x86-64 instruction set is supported */
+# if defined(_LP64) || defined(__LP64__) || defined(__x86_64) || \
+ defined(__x86_64__) || defined(_M_AMD64) || defined(_M_X64)
+# define CPU_X64
+# else
+# define CPU_IA32
+# endif
+#endif
+
+
+/* detect CPU endianness */
+#include <cm_kwiml.h>
+#if KWIML_ABI_ENDIAN_ID == KWIML_ABI_ENDIAN_ID_LITTLE
+# define CPU_LITTLE_ENDIAN
+# define IS_BIG_ENDIAN 0
+# define IS_LITTLE_ENDIAN 1
+#elif KWIML_ABI_ENDIAN_ID == KWIML_ABI_ENDIAN_ID_BIG
+# define CPU_BIG_ENDIAN
+# define IS_BIG_ENDIAN 1
+# define IS_LITTLE_ENDIAN 0
+#else
+# error "Can't detect CPU architechture"
+#endif
+
+#define IS_ALIGNED_32(p) (0 == (3 & ((const char*)(p) - (const char*)0)))
+#define IS_ALIGNED_64(p) (0 == (7 & ((const char*)(p) - (const char*)0)))
+
+#if defined(_MSC_VER)
+#define ALIGN_ATTR(n) __declspec(align(n))
+#elif defined(__GNUC__)
+#define ALIGN_ATTR(n) __attribute__((aligned (n)))
+#else
+#define ALIGN_ATTR(n) /* nothing */
+#endif
+
+
+#if defined(_MSC_VER) || defined(__BORLANDC__)
+#define I64(x) x##ui64
+#else
+#define I64(x) x##LL
+#endif
+
+/* convert a hash flag to index */
+#if __GNUC__ >= 4 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) /* GCC < 3.4 */
+# define rhash_ctz(x) __builtin_ctz(x)
+#else
+unsigned rhash_ctz(unsigned); /* define as function */
+#endif
+
+void rhash_swap_copy_str_to_u32(void* to, int index, const void* from, size_t length);
+void rhash_swap_copy_str_to_u64(void* to, int index, const void* from, size_t length);
+void rhash_swap_copy_u64_to_str(void* to, const void* from, size_t length);
+void rhash_u32_mem_swap(unsigned *p, int length_in_u32);
+
+#ifndef __has_builtin
+# define __has_builtin(x) 0
+#endif
+
+/* define bswap_32 */
+#if defined(__GNUC__) && defined(CPU_IA32) && !defined(__i386__)
+/* for intel x86 CPU */
+static inline uint32_t bswap_32(uint32_t x) {
+ __asm("bswap\t%0" : "=r" (x) : "0" (x));
+ return x;
+}
+#elif defined(__GNUC__) && (__GNUC__ >= 4) && (__GNUC__ > 4 || __GNUC_MINOR__ >= 3)
+/* for GCC >= 4.3 */
+# define bswap_32(x) __builtin_bswap32(x)
+#elif defined(__clang__) && __has_builtin(__builtin_bswap32)
+# define bswap_32(x) __builtin_bswap32(x)
+#elif (_MSC_VER > 1300) && (defined(CPU_IA32) || defined(CPU_X64)) /* MS VC */
+# define bswap_32(x) _byteswap_ulong((unsigned long)x)
+#else
+/* general bswap_32 definition */
+static uint32_t bswap_32(uint32_t x) {
+ x = ((x << 8) & 0xFF00FF00) | ((x >> 8) & 0x00FF00FF);
+ return (x >> 16) | (x << 16);
+}
+#endif /* bswap_32 */
+
+#if defined(__GNUC__) && (__GNUC__ >= 4) && (__GNUC__ > 4 || __GNUC_MINOR__ >= 3)
+# define bswap_64(x) __builtin_bswap64(x)
+#elif defined(__clang__) && __has_builtin(__builtin_bswap64)
+# define bswap_64(x) __builtin_bswap64(x)
+#elif (_MSC_VER > 1300) && (defined(CPU_IA32) || defined(CPU_X64)) /* MS VC */
+# define bswap_64(x) _byteswap_uint64((__int64)x)
+#else
+static uint64_t bswap_64(uint64_t x) {
+ union {
+ uint64_t ll;
+ uint32_t l[2];
+ } w, r;
+ w.ll = x;
+ r.l[0] = bswap_32(w.l[1]);
+ r.l[1] = bswap_32(w.l[0]);
+ return r.ll;
+}
+#endif
+
+#ifdef CPU_BIG_ENDIAN
+# define be2me_32(x) (x)
+# define be2me_64(x) (x)
+# define le2me_32(x) bswap_32(x)
+# define le2me_64(x) bswap_64(x)
+
+# define be32_copy(to, index, from, length) memcpy((to) + (index), (from), (length))
+# define le32_copy(to, index, from, length) rhash_swap_copy_str_to_u32((to), (index), (from), (length))
+# define be64_copy(to, index, from, length) memcpy((to) + (index), (from), (length))
+# define le64_copy(to, index, from, length) rhash_swap_copy_str_to_u64((to), (index), (from), (length))
+# define me64_to_be_str(to, from, length) memcpy((to), (from), (length))
+# define me64_to_le_str(to, from, length) rhash_swap_copy_u64_to_str((to), (from), (length))
+
+#else /* CPU_BIG_ENDIAN */
+# define be2me_32(x) bswap_32(x)
+# define be2me_64(x) bswap_64(x)
+# define le2me_32(x) (x)
+# define le2me_64(x) (x)
+
+# define be32_copy(to, index, from, length) rhash_swap_copy_str_to_u32((to), (index), (from), (length))
+# define le32_copy(to, index, from, length) memcpy((to) + (index), (from), (length))
+# define be64_copy(to, index, from, length) rhash_swap_copy_str_to_u64((to), (index), (from), (length))
+# define le64_copy(to, index, from, length) memcpy((to) + (index), (from), (length))
+# define me64_to_be_str(to, from, length) rhash_swap_copy_u64_to_str((to), (from), (length))
+# define me64_to_le_str(to, from, length) memcpy((to), (from), (length))
+#endif /* CPU_BIG_ENDIAN */
+
+/* ROTL/ROTR macros rotate a 32/64-bit word left/right by n bits */
+#define ROTL32(dword, n) ((dword) << (n) ^ ((dword) >> (32 - (n))))
+#define ROTR32(dword, n) ((dword) >> (n) ^ ((dword) << (32 - (n))))
+#define ROTL64(qword, n) ((qword) << (n) ^ ((qword) >> (64 - (n))))
+#define ROTR64(qword, n) ((qword) >> (n) ^ ((qword) << (64 - (n))))
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif /* __cplusplus */
+
+#endif /* BYTE_ORDER_H */
diff --git a/Utilities/cmlibrhash/librhash/hex.c b/Utilities/cmlibrhash/librhash/hex.c
new file mode 100644
index 0000000..c941149
--- /dev/null
+++ b/Utilities/cmlibrhash/librhash/hex.c
@@ -0,0 +1,188 @@
+/* hex.c - conversion for hexadecimal and base32 strings.
+ *
+ * Copyright: 2008-2012 Aleksey Kravchenko <rhash.admin@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. Use this program at your own risk!
+ */
+#include <string.h>
+#include <ctype.h>
+#include "hex.h"
+
+/**
+* Convert a byte to a hexadecimal number. The result, consisting of two
+* hexadecimal digits is stored into a buffer.
+ *
+ * @param dest the buffer to receive two symbols of hex representation
+ * @param byte the byte to decode
+ * @param upper_case flag to print string in uppercase
+ * @return pointer to the chararcter just after the written number (dest + 2)
+ */
+char* rhash_print_hex_byte(char *dest, const unsigned char byte, int upper_case)
+{
+ const char add = (upper_case ? 'A' - 10 : 'a' - 10);
+ unsigned char c = (byte >> 4) & 15;
+ *dest++ = (c > 9 ? c + add : c + '0');
+ c = byte & 15;
+ *dest++ = (c > 9 ? c + add : c + '0');
+ return dest;
+}
+
+/**
+ * Store hexadecimal representation of a binary string to given buffer.
+ *
+ * @param dest the buffer to receive hexadecimal representation
+ * @param src binary string
+ * @param len string length
+ * @param upper_case flag to print string in uppercase
+ */
+void rhash_byte_to_hex(char *dest, const unsigned char *src, unsigned len, int upper_case)
+{
+ while (len-- > 0) {
+ dest = rhash_print_hex_byte(dest, *src++, upper_case);
+ }
+ *dest = '\0';
+}
+
+/**
+ * Encode a binary string to base32.
+ *
+ * @param dest the buffer to store result
+ * @param src binary string
+ * @param len string length
+ * @param upper_case flag to print string in uppercase
+ */
+void rhash_byte_to_base32(char* dest, const unsigned char* src, unsigned len, int upper_case)
+{
+ const char a = (upper_case ? 'A' : 'a');
+ unsigned shift = 0;
+ unsigned char word;
+ const unsigned char* e = src + len;
+ while (src < e) {
+ if (shift > 3) {
+ word = (*src & (0xFF >> shift));
+ shift = (shift + 5) % 8;
+ word <<= shift;
+ if (src + 1 < e)
+ word |= *(src + 1) >> (8 - shift);
+ ++src;
+ } else {
+ shift = (shift + 5) % 8;
+ word = ( *src >> ( (8 - shift) & 7 ) ) & 0x1F;
+ if (shift == 0) src++;
+ }
+ *dest++ = ( word < 26 ? word + a : word + '2' - 26 );
+ }
+ *dest = '\0';
+}
+
+/**
+ * Encode a binary string to base64.
+ * Encoded output length is always a multiple of 4 bytes.
+ *
+ * @param dest the buffer to store result
+ * @param src binary string
+ * @param len string length
+ */
+void rhash_byte_to_base64(char* dest, const unsigned char* src, unsigned len)
+{
+ static const char* tail = "0123456789+/";
+ unsigned shift = 0;
+ unsigned char word;
+ const unsigned char* e = src + len;
+ while (src < e) {
+ if (shift > 2) {
+ word = (*src & (0xFF >> shift));
+ shift = (shift + 6) % 8;
+ word <<= shift;
+ if (src + 1 < e)
+ word |= *(src + 1) >> (8 - shift);
+ ++src;
+ } else {
+ shift = (shift + 6) % 8;
+ word = ( *src >> ( (8 - shift) & 7 ) ) & 0x3F;
+ if (shift == 0) src++;
+ }
+ *dest++ = ( word < 52 ? (word < 26 ? word + 'A' : word - 26 + 'a') : tail[word - 52]);
+ }
+ if (shift > 0) {
+ *dest++ = '=';
+ if (shift == 4) *dest++ = '=';
+ }
+ *dest = '\0';
+}
+
+/* unsafe characters are "<>{}[]%#/|\^~`@:;?=&+ */
+#define IS_GOOD_URL_CHAR(c) (isalnum((unsigned char)c) || strchr("$-_.!'(),", c))
+
+/**
+ * URL-encode a string.
+ *
+ * @param dst buffer to receive result or NULL to calculate
+ * the lengths of encoded string
+ * @param filename the file name
+ * @return the length of the result string
+ */
+int rhash_urlencode(char *dst, const char *name)
+{
+ const char *start;
+ if (!dst) {
+ int len;
+ for (len = 0; *name; name++) len += (IS_GOOD_URL_CHAR(*name) ? 1 : 3);
+ return len;
+ }
+ /* encode URL as specified by RFC 1738 */
+ for (start = dst; *name; name++) {
+ if ( IS_GOOD_URL_CHAR(*name) ) {
+ *dst++ = *name;
+ } else {
+ *dst++ = '%';
+ dst = rhash_print_hex_byte(dst, *name, 'A');
+ }
+ }
+ *dst = 0;
+ return (int)(dst - start);
+}
+
+/**
+ * Print 64-bit number with trailing '\0' to a string buffer.
+ * if dst is NULL, then just return the length of the number.
+ *
+ * @param dst output buffer
+ * @param number the number to print
+ * @return length of the printed number (without trailing '\0')
+ */
+int rhash_sprintI64(char *dst, uint64_t number)
+{
+ /* The biggest number has 20 digits: 2^64 = 18 446 744 073 709 551 616 */
+ char buf[24], *p;
+ size_t length;
+
+ if (dst == NULL) {
+ /* just calculate the length of the number */
+ if (number == 0) return 1;
+ for (length = 0; number != 0; number /= 10) length++;
+ return (int)length;
+ }
+
+ p = buf + 23;
+ *p = '\0'; /* last symbol should be '\0' */
+ if (number == 0) {
+ *(--p) = '0';
+ } else {
+ for (; p >= buf && number != 0; number /= 10) {
+ *(--p) = '0' + (char)(number % 10);
+ }
+ }
+ length = buf + 23 - p;
+ memcpy(dst, p, length + 1);
+ return (int)length;
+}
diff --git a/Utilities/cmlibrhash/librhash/hex.h b/Utilities/cmlibrhash/librhash/hex.h
new file mode 100644
index 0000000..2b365e2
--- /dev/null
+++ b/Utilities/cmlibrhash/librhash/hex.h
@@ -0,0 +1,25 @@
+/* hex.h - conversion for hexadecimal and base32 strings. */
+#ifndef HEX_H
+#define HEX_H
+
+#include "ustd.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void rhash_byte_to_hex(char *dest, const unsigned char *src, unsigned len, int upper_case);
+void rhash_byte_to_base32(char* dest, const unsigned char* src, unsigned len, int upper_case);
+void rhash_byte_to_base64(char* dest, const unsigned char* src, unsigned len);
+char* rhash_print_hex_byte(char *dest, const unsigned char byte, int upper_case);
+int rhash_urlencode(char *dst, const char *name);
+int rhash_sprintI64(char *dst, uint64_t number);
+
+#define BASE32_LENGTH(bytes) (((bytes) * 8 + 4) / 5)
+#define BASE64_LENGTH(bytes) ((((bytes) + 2) / 3) * 4)
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif /* __cplusplus */
+
+#endif /* HEX_H */
diff --git a/Utilities/cmlibrhash/librhash/md5.c b/Utilities/cmlibrhash/librhash/md5.c
new file mode 100644
index 0000000..b20de45
--- /dev/null
+++ b/Utilities/cmlibrhash/librhash/md5.c
@@ -0,0 +1,236 @@
+/* md5.c - an implementation of the MD5 algorithm, based on RFC 1321.
+ *
+ * Copyright: 2007-2012 Aleksey Kravchenko <rhash.admin@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. Use this program at your own risk!
+ */
+
+#include <string.h>
+#include "byte_order.h"
+#include "md5.h"
+
+/**
+ * Initialize context before calculaing hash.
+ *
+ * @param ctx context to initialize
+ */
+void rhash_md5_init(md5_ctx *ctx)
+{
+ ctx->length = 0;
+
+ /* initialize state */
+ ctx->hash[0] = 0x67452301;
+ ctx->hash[1] = 0xefcdab89;
+ ctx->hash[2] = 0x98badcfe;
+ ctx->hash[3] = 0x10325476;
+}
+
+/* First, define four auxiliary functions that each take as input
+ * three 32-bit words and returns a 32-bit word.*/
+
+/* F(x,y,z) = ((y XOR z) AND x) XOR z - is faster then original version */
+#define MD5_F(x, y, z) ((((y) ^ (z)) & (x)) ^ (z))
+#define MD5_G(x, y, z) (((x) & (z)) | ((y) & (~z)))
+#define MD5_H(x, y, z) ((x) ^ (y) ^ (z))
+#define MD5_I(x, y, z) ((y) ^ ((x) | (~z)))
+
+/* transformations for rounds 1, 2, 3, and 4. */
+#define MD5_ROUND1(a, b, c, d, x, s, ac) { \
+ (a) += MD5_F((b), (c), (d)) + (x) + (ac); \
+ (a) = ROTL32((a), (s)); \
+ (a) += (b); \
+}
+#define MD5_ROUND2(a, b, c, d, x, s, ac) { \
+ (a) += MD5_G((b), (c), (d)) + (x) + (ac); \
+ (a) = ROTL32((a), (s)); \
+ (a) += (b); \
+}
+#define MD5_ROUND3(a, b, c, d, x, s, ac) { \
+ (a) += MD5_H((b), (c), (d)) + (x) + (ac); \
+ (a) = ROTL32((a), (s)); \
+ (a) += (b); \
+}
+#define MD5_ROUND4(a, b, c, d, x, s, ac) { \
+ (a) += MD5_I((b), (c), (d)) + (x) + (ac); \
+ (a) = ROTL32((a), (s)); \
+ (a) += (b); \
+}
+
+/**
+ * The core transformation. Process a 512-bit block.
+ * The function has been taken from RFC 1321 with little changes.
+ *
+ * @param state algorithm state
+ * @param x the message block to process
+ */
+static void rhash_md5_process_block(unsigned state[4], const unsigned* x)
+{
+ register unsigned a, b, c, d;
+ a = state[0];
+ b = state[1];
+ c = state[2];
+ d = state[3];
+
+ MD5_ROUND1(a, b, c, d, x[ 0], 7, 0xd76aa478);
+ MD5_ROUND1(d, a, b, c, x[ 1], 12, 0xe8c7b756);
+ MD5_ROUND1(c, d, a, b, x[ 2], 17, 0x242070db);
+ MD5_ROUND1(b, c, d, a, x[ 3], 22, 0xc1bdceee);
+ MD5_ROUND1(a, b, c, d, x[ 4], 7, 0xf57c0faf);
+ MD5_ROUND1(d, a, b, c, x[ 5], 12, 0x4787c62a);
+ MD5_ROUND1(c, d, a, b, x[ 6], 17, 0xa8304613);
+ MD5_ROUND1(b, c, d, a, x[ 7], 22, 0xfd469501);
+ MD5_ROUND1(a, b, c, d, x[ 8], 7, 0x698098d8);
+ MD5_ROUND1(d, a, b, c, x[ 9], 12, 0x8b44f7af);
+ MD5_ROUND1(c, d, a, b, x[10], 17, 0xffff5bb1);
+ MD5_ROUND1(b, c, d, a, x[11], 22, 0x895cd7be);
+ MD5_ROUND1(a, b, c, d, x[12], 7, 0x6b901122);
+ MD5_ROUND1(d, a, b, c, x[13], 12, 0xfd987193);
+ MD5_ROUND1(c, d, a, b, x[14], 17, 0xa679438e);
+ MD5_ROUND1(b, c, d, a, x[15], 22, 0x49b40821);
+
+ MD5_ROUND2(a, b, c, d, x[ 1], 5, 0xf61e2562);
+ MD5_ROUND2(d, a, b, c, x[ 6], 9, 0xc040b340);
+ MD5_ROUND2(c, d, a, b, x[11], 14, 0x265e5a51);
+ MD5_ROUND2(b, c, d, a, x[ 0], 20, 0xe9b6c7aa);
+ MD5_ROUND2(a, b, c, d, x[ 5], 5, 0xd62f105d);
+ MD5_ROUND2(d, a, b, c, x[10], 9, 0x2441453);
+ MD5_ROUND2(c, d, a, b, x[15], 14, 0xd8a1e681);
+ MD5_ROUND2(b, c, d, a, x[ 4], 20, 0xe7d3fbc8);
+ MD5_ROUND2(a, b, c, d, x[ 9], 5, 0x21e1cde6);
+ MD5_ROUND2(d, a, b, c, x[14], 9, 0xc33707d6);
+ MD5_ROUND2(c, d, a, b, x[ 3], 14, 0xf4d50d87);
+ MD5_ROUND2(b, c, d, a, x[ 8], 20, 0x455a14ed);
+ MD5_ROUND2(a, b, c, d, x[13], 5, 0xa9e3e905);
+ MD5_ROUND2(d, a, b, c, x[ 2], 9, 0xfcefa3f8);
+ MD5_ROUND2(c, d, a, b, x[ 7], 14, 0x676f02d9);
+ MD5_ROUND2(b, c, d, a, x[12], 20, 0x8d2a4c8a);
+
+ MD5_ROUND3(a, b, c, d, x[ 5], 4, 0xfffa3942);
+ MD5_ROUND3(d, a, b, c, x[ 8], 11, 0x8771f681);
+ MD5_ROUND3(c, d, a, b, x[11], 16, 0x6d9d6122);
+ MD5_ROUND3(b, c, d, a, x[14], 23, 0xfde5380c);
+ MD5_ROUND3(a, b, c, d, x[ 1], 4, 0xa4beea44);
+ MD5_ROUND3(d, a, b, c, x[ 4], 11, 0x4bdecfa9);
+ MD5_ROUND3(c, d, a, b, x[ 7], 16, 0xf6bb4b60);
+ MD5_ROUND3(b, c, d, a, x[10], 23, 0xbebfbc70);
+ MD5_ROUND3(a, b, c, d, x[13], 4, 0x289b7ec6);
+ MD5_ROUND3(d, a, b, c, x[ 0], 11, 0xeaa127fa);
+ MD5_ROUND3(c, d, a, b, x[ 3], 16, 0xd4ef3085);
+ MD5_ROUND3(b, c, d, a, x[ 6], 23, 0x4881d05);
+ MD5_ROUND3(a, b, c, d, x[ 9], 4, 0xd9d4d039);
+ MD5_ROUND3(d, a, b, c, x[12], 11, 0xe6db99e5);
+ MD5_ROUND3(c, d, a, b, x[15], 16, 0x1fa27cf8);
+ MD5_ROUND3(b, c, d, a, x[ 2], 23, 0xc4ac5665);
+
+ MD5_ROUND4(a, b, c, d, x[ 0], 6, 0xf4292244);
+ MD5_ROUND4(d, a, b, c, x[ 7], 10, 0x432aff97);
+ MD5_ROUND4(c, d, a, b, x[14], 15, 0xab9423a7);
+ MD5_ROUND4(b, c, d, a, x[ 5], 21, 0xfc93a039);
+ MD5_ROUND4(a, b, c, d, x[12], 6, 0x655b59c3);
+ MD5_ROUND4(d, a, b, c, x[ 3], 10, 0x8f0ccc92);
+ MD5_ROUND4(c, d, a, b, x[10], 15, 0xffeff47d);
+ MD5_ROUND4(b, c, d, a, x[ 1], 21, 0x85845dd1);
+ MD5_ROUND4(a, b, c, d, x[ 8], 6, 0x6fa87e4f);
+ MD5_ROUND4(d, a, b, c, x[15], 10, 0xfe2ce6e0);
+ MD5_ROUND4(c, d, a, b, x[ 6], 15, 0xa3014314);
+ MD5_ROUND4(b, c, d, a, x[13], 21, 0x4e0811a1);
+ MD5_ROUND4(a, b, c, d, x[ 4], 6, 0xf7537e82);
+ MD5_ROUND4(d, a, b, c, x[11], 10, 0xbd3af235);
+ MD5_ROUND4(c, d, a, b, x[ 2], 15, 0x2ad7d2bb);
+ MD5_ROUND4(b, c, d, a, x[ 9], 21, 0xeb86d391);
+
+ state[0] += a;
+ state[1] += b;
+ state[2] += c;
+ state[3] += d;
+}
+
+/**
+ * Calculate message hash.
+ * Can be called repeatedly with chunks of the message to be hashed.
+ *
+ * @param ctx the algorithm context containing current hashing state
+ * @param msg message chunk
+ * @param size length of the message chunk
+ */
+void rhash_md5_update(md5_ctx *ctx, const unsigned char* msg, size_t size)
+{
+ unsigned index = (unsigned)ctx->length & 63;
+ ctx->length += size;
+
+ /* fill partial block */
+ if (index) {
+ unsigned left = md5_block_size - index;
+ le32_copy((char*)ctx->message, index, msg, (size < left ? size : left));
+ if (size < left) return;
+
+ /* process partial block */
+ rhash_md5_process_block(ctx->hash, ctx->message);
+ msg += left;
+ size -= left;
+ }
+ while (size >= md5_block_size) {
+ unsigned* aligned_message_block;
+ if (IS_LITTLE_ENDIAN && IS_ALIGNED_32(msg)) {
+ /* the most common case is processing a 32-bit aligned message
+ on a little-endian CPU without copying it */
+ aligned_message_block = (unsigned*)msg;
+ } else {
+ le32_copy(ctx->message, 0, msg, md5_block_size);
+ aligned_message_block = ctx->message;
+ }
+
+ rhash_md5_process_block(ctx->hash, aligned_message_block);
+ msg += md5_block_size;
+ size -= md5_block_size;
+ }
+ if (size) {
+ /* save leftovers */
+ le32_copy(ctx->message, 0, msg, size);
+ }
+}
+
+/**
+ * Store calculated hash into the given array.
+ *
+ * @param ctx the algorithm context containing current hashing state
+ * @param result calculated hash in binary form
+ */
+void rhash_md5_final(md5_ctx *ctx, unsigned char* result)
+{
+ unsigned index = ((unsigned)ctx->length & 63) >> 2;
+ unsigned shift = ((unsigned)ctx->length & 3) * 8;
+
+ /* pad message and run for last block */
+
+ /* append the byte 0x80 to the message */
+ ctx->message[index] &= ~(0xFFFFFFFFu << shift);
+ ctx->message[index++] ^= 0x80u << shift;
+
+ /* if no room left in the message to store 64-bit message length */
+ if (index > 14) {
+ /* then fill the rest with zeros and process it */
+ while (index < 16) {
+ ctx->message[index++] = 0;
+ }
+ rhash_md5_process_block(ctx->hash, ctx->message);
+ index = 0;
+ }
+ while (index < 14) {
+ ctx->message[index++] = 0;
+ }
+ ctx->message[14] = (unsigned)(ctx->length << 3);
+ ctx->message[15] = (unsigned)(ctx->length >> 29);
+ rhash_md5_process_block(ctx->hash, ctx->message);
+
+ if (result) le32_copy(result, 0, &ctx->hash, 16);
+}
diff --git a/Utilities/cmlibrhash/librhash/md5.h b/Utilities/cmlibrhash/librhash/md5.h
new file mode 100644
index 0000000..1af6f13
--- /dev/null
+++ b/Utilities/cmlibrhash/librhash/md5.h
@@ -0,0 +1,31 @@
+/* md5.h */
+#ifndef MD5_HIDER
+#define MD5_HIDER
+#include "ustd.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define md5_block_size 64
+#define md5_hash_size 16
+
+/* algorithm context */
+typedef struct md5_ctx
+{
+ unsigned message[md5_block_size / 4]; /* 512-bit buffer for leftovers */
+ uint64_t length; /* number of processed bytes */
+ unsigned hash[4]; /* 128-bit algorithm internal hashing state */
+} md5_ctx;
+
+/* hash functions */
+
+void rhash_md5_init(md5_ctx *ctx);
+void rhash_md5_update(md5_ctx *ctx, const unsigned char* msg, size_t size);
+void rhash_md5_final(md5_ctx *ctx, unsigned char result[16]);
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif /* __cplusplus */
+
+#endif /* MD5_HIDER */
diff --git a/Utilities/cmlibrhash/librhash/rhash.c b/Utilities/cmlibrhash/librhash/rhash.c
new file mode 100644
index 0000000..ad6249b
--- /dev/null
+++ b/Utilities/cmlibrhash/librhash/rhash.c
@@ -0,0 +1,872 @@
+/* rhash.c - implementation of LibRHash library calls
+ *
+ * Copyright: 2008-2012 Aleksey Kravchenko <rhash.admin@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. Use this program at your own risk!
+ */
+
+/* macros for large file support, must be defined before any include file */
+#define _LARGEFILE64_SOURCE
+#define _FILE_OFFSET_BITS 64
+
+#include <string.h> /* memset() */
+#include <stdlib.h> /* free() */
+#include <stddef.h> /* ptrdiff_t */
+#include <stdio.h>
+#include <assert.h>
+#include <errno.h>
+
+/* modifier for Windows DLL */
+#if defined(_WIN32) && defined(RHASH_EXPORTS)
+# define RHASH_API __declspec(dllexport)
+#endif
+
+#include "byte_order.h"
+#include "algorithms.h"
+#include "util.h"
+#include "hex.h"
+#include "rhash.h" /* RHash library interface */
+
+#define STATE_ACTIVE 0xb01dbabe
+#define STATE_STOPED 0xdeadbeef
+#define STATE_DELETED 0xdecea5ed
+#define RCTX_AUTO_FINAL 0x1
+#define RCTX_FINALIZED 0x2
+#define RCTX_FINALIZED_MASK (RCTX_AUTO_FINAL | RCTX_FINALIZED)
+#define RHPR_FORMAT (RHPR_RAW | RHPR_HEX | RHPR_BASE32 | RHPR_BASE64)
+#define RHPR_MODIFIER (RHPR_UPPERCASE | RHPR_REVERSE)
+
+/**
+ * Initialize static data of rhash algorithms
+ */
+void rhash_library_init(void)
+{
+ rhash_init_algorithms(RHASH_ALL_HASHES);
+#ifdef USE_OPENSSL
+ rhash_plug_openssl();
+#endif
+}
+
+/**
+ * Returns the number of supported hash algorithms.
+ *
+ * @return the number of supported hash functions
+ */
+int RHASH_API rhash_count(void)
+{
+ return rhash_info_size;
+}
+
+/* Lo-level rhash library functions */
+
+/**
+ * Allocate and initialize RHash context for calculating hash(es).
+ * After initializing rhash_update()/rhash_final() functions should be used.
+ * Then the context must be freed by calling rhash_free().
+ *
+ * @param hash_id union of bit flags, containing ids of hashes to calculate.
+ * @return initialized rhash context, NULL on error and errno is set
+ */
+RHASH_API rhash rhash_init(unsigned hash_id)
+{
+ unsigned tail_bit_index; /* index of hash_id trailing bit */
+ unsigned num = 0; /* number of hashes to compute */
+ rhash_context_ext *rctx = NULL; /* allocated rhash context */
+ size_t hash_size_sum = 0; /* size of hash contexts to store in rctx */
+
+ unsigned i, bit_index, id;
+ struct rhash_hash_info* info;
+ size_t aligned_size;
+ char* phash_ctx;
+
+ hash_id &= RHASH_ALL_HASHES;
+ if (hash_id == 0) {
+ errno = EINVAL;
+ return NULL;
+ }
+
+ tail_bit_index = rhash_ctz(hash_id); /* get trailing bit index */
+ assert(tail_bit_index < RHASH_HASH_COUNT);
+
+ id = 1 << tail_bit_index;
+
+ if (hash_id == id) {
+ /* handle the most common case of only one hash */
+ num = 1;
+ info = &rhash_info_table[tail_bit_index];
+ hash_size_sum = info->context_size;
+ } else {
+ /* another case: hash_id contains several hashes */
+ for (bit_index = tail_bit_index; id <= hash_id; bit_index++, id = id << 1) {
+ assert(id != 0);
+ assert(bit_index < RHASH_HASH_COUNT);
+ info = &rhash_info_table[bit_index];
+ if (hash_id & id) {
+ /* align sizes by 8 bytes */
+ aligned_size = (info->context_size + 7) & ~7;
+ hash_size_sum += aligned_size;
+ num++;
+ }
+ }
+ assert(num > 1);
+ }
+
+ /* align the size of the rhash context common part */
+ aligned_size = (offsetof(rhash_context_ext, vector[num]) + 7) & ~7;
+ assert(aligned_size >= sizeof(rhash_context_ext));
+
+ /* allocate rhash context with enough memory to store contexts of all used hashes */
+ rctx = (rhash_context_ext*)malloc(aligned_size + hash_size_sum);
+ if (rctx == NULL) return NULL;
+
+ /* initialize common fields of the rhash context */
+ memset(rctx, 0, sizeof(rhash_context_ext));
+ rctx->rc.hash_id = hash_id;
+ rctx->flags = RCTX_AUTO_FINAL; /* turn on auto-final by default */
+ rctx->state = STATE_ACTIVE;
+ rctx->hash_vector_size = num;
+
+ /* aligned hash contexts follows rctx->vector[num] in the same memory block */
+ phash_ctx = (char*)rctx + aligned_size;
+ assert(phash_ctx >= (char*)&rctx->vector[num]);
+
+ /* initialize context for every hash in a loop */
+ for (bit_index = tail_bit_index, id = 1 << tail_bit_index, i = 0;
+ id <= hash_id; bit_index++, id = id << 1)
+ {
+ /* check if a hash function with given id shall be included into rctx */
+ if ((hash_id & id) != 0) {
+ info = &rhash_info_table[bit_index];
+ assert(info->context_size > 0);
+ assert(((phash_ctx - (char*)0) & 7) == 0); /* hash context is aligned */
+ assert(info->init != NULL);
+
+ rctx->vector[i].hash_info = info;
+ rctx->vector[i].context = phash_ctx;
+
+#if 0
+ /* BTIH initialization is complex, save pointer for later */
+ if ((id & RHASH_BTIH) != 0) rctx->bt_ctx = phash_ctx;
+#endif
+ phash_ctx += (info->context_size + 7) & ~7;
+
+ /* initialize the i-th hash context */
+ info->init(rctx->vector[i].context);
+ i++;
+ }
+ }
+
+ return &rctx->rc; /* return allocated and initialized rhash context */
+}
+
+/**
+ * Free RHash context memory.
+ *
+ * @param ctx the context to free.
+ */
+void rhash_free(rhash ctx)
+{
+ rhash_context_ext* const ectx = (rhash_context_ext*)ctx;
+ unsigned i;
+
+ if (ctx == 0) return;
+ assert(ectx->hash_vector_size <= RHASH_HASH_COUNT);
+ ectx->state = STATE_DELETED; /* mark memory block as being removed */
+
+ /* clean the hash functions, which require additional clean up */
+ for (i = 0; i < ectx->hash_vector_size; i++) {
+ struct rhash_hash_info* info = ectx->vector[i].hash_info;
+ if (info->cleanup != 0) {
+ info->cleanup(ectx->vector[i].context);
+ }
+ }
+
+ free(ectx);
+}
+
+/**
+ * Re-initialize RHash context to reuse it.
+ * Useful to speed up processing of many small messages.
+ *
+ * @param ctx context to reinitialize
+ */
+RHASH_API void rhash_reset(rhash ctx)
+{
+ rhash_context_ext* const ectx = (rhash_context_ext*)ctx;
+ unsigned i;
+
+ assert(ectx->hash_vector_size > 0);
+ assert(ectx->hash_vector_size <= RHASH_HASH_COUNT);
+ ectx->state = STATE_ACTIVE; /* re-activate the structure */
+
+ /* re-initialize every hash in a loop */
+ for (i = 0; i < ectx->hash_vector_size; i++) {
+ struct rhash_hash_info* info = ectx->vector[i].hash_info;
+ if (info->cleanup != 0) {
+ info->cleanup(ectx->vector[i].context);
+ }
+
+ assert(info->init != NULL);
+ info->init(ectx->vector[i].context);
+ }
+ ectx->flags &= ~RCTX_FINALIZED; /* clear finalized state */
+}
+
+/**
+ * Calculate hashes of message.
+ * Can be called repeatedly with chunks of the message to be hashed.
+ *
+ * @param ctx the rhash context
+ * @param message message chunk
+ * @param length length of the message chunk
+ * @return 0 on success; On fail return -1 and set errno
+ */
+RHASH_API int rhash_update(rhash ctx, const void* message, size_t length)
+{
+ rhash_context_ext* const ectx = (rhash_context_ext*)ctx;
+ unsigned i;
+
+ assert(ectx->hash_vector_size <= RHASH_HASH_COUNT);
+ if (ectx->state != STATE_ACTIVE) return 0; /* do nothing if canceled */
+
+ ctx->msg_size += length;
+
+ /* call update method for every algorithm */
+ for (i = 0; i < ectx->hash_vector_size; i++) {
+ struct rhash_hash_info* info = ectx->vector[i].hash_info;
+ assert(info->update != 0);
+ info->update(ectx->vector[i].context, message, length);
+ }
+ return 0; /* no error processing at the moment */
+}
+
+/**
+ * Finalize hash calculation and optionally store the first hash.
+ *
+ * @param ctx the rhash context
+ * @param first_result optional buffer to store a calculated hash with the lowest available id
+ * @return 0 on success; On fail return -1 and set errno
+ */
+RHASH_API int rhash_final(rhash ctx, unsigned char* first_result)
+{
+ unsigned i = 0;
+ unsigned char buffer[130];
+ unsigned char* out = (first_result ? first_result : buffer);
+ rhash_context_ext* const ectx = (rhash_context_ext*)ctx;
+ assert(ectx->hash_vector_size <= RHASH_HASH_COUNT);
+
+ /* skip final call if already finalized and auto-final is on */
+ if ((ectx->flags & RCTX_FINALIZED_MASK) ==
+ (RCTX_AUTO_FINAL | RCTX_FINALIZED)) return 0;
+
+ /* call final method for every algorithm */
+ for (i = 0; i < ectx->hash_vector_size; i++) {
+ struct rhash_hash_info* info = ectx->vector[i].hash_info;
+ assert(info->final != 0);
+ assert(info->info->digest_size < sizeof(buffer));
+ info->final(ectx->vector[i].context, out);
+ out = buffer;
+ }
+ ectx->flags |= RCTX_FINALIZED;
+ return 0; /* no error processing at the moment */
+}
+
+/**
+ * Store digest for given hash_id.
+ * If hash_id is zero, function stores digest for a hash with the lowest id found in the context.
+ * For nonzero hash_id the context must contain it, otherwise function silently does nothing.
+ *
+ * @param ctx rhash context
+ * @param hash_id id of hash to retrieve or zero for hash with the lowest available id
+ * @param result buffer to put the hash into
+ */
+static void rhash_put_digest(rhash ctx, unsigned hash_id, unsigned char* result)
+{
+ rhash_context_ext* const ectx = (rhash_context_ext*)ctx;
+ unsigned i;
+ rhash_vector_item *item;
+ struct rhash_hash_info* info;
+ unsigned char* digest;
+
+ assert(ectx);
+ assert(ectx->hash_vector_size > 0 && ectx->hash_vector_size <= RHASH_HASH_COUNT);
+
+ /* finalize context if not yet finalized and auto-final is on */
+ if ((ectx->flags & RCTX_FINALIZED_MASK) == RCTX_AUTO_FINAL) {
+ rhash_final(ctx, NULL);
+ }
+
+ if (hash_id == 0) {
+ item = &ectx->vector[0]; /* get the first hash */
+ info = item->hash_info;
+ } else {
+ for (i = 0;; i++) {
+ if (i >= ectx->hash_vector_size) {
+ return; /* hash_id not found, do nothing */
+ }
+ item = &ectx->vector[i];
+ info = item->hash_info;
+ if (info->info->hash_id == hash_id) break;
+ }
+ }
+ digest = ((unsigned char*)item->context + info->digest_diff);
+ if (info->info->flags & F_SWAP32) {
+ assert((info->info->digest_size & 3) == 0);
+ /* NB: the next call is correct only for multiple of 4 byte size */
+ rhash_swap_copy_str_to_u32(result, 0, digest, info->info->digest_size);
+ } else if (info->info->flags & F_SWAP64) {
+ rhash_swap_copy_u64_to_str(result, digest, info->info->digest_size);
+ } else {
+ memcpy(result, digest, info->info->digest_size);
+ }
+}
+
+/**
+ * Set the callback function to be called from the
+ * rhash_file() and rhash_file_update() functions
+ * on processing every file block. The file block
+ * size is set internally by rhash and now is 8 KiB.
+ *
+ * @param ctx rhash context
+ * @param callback pointer to the callback function
+ * @param callback_data pointer to data passed to the callback
+ */
+RHASH_API void rhash_set_callback(rhash ctx, rhash_callback_t callback, void* callback_data)
+{
+ ((rhash_context_ext*)ctx)->callback = callback;
+ ((rhash_context_ext*)ctx)->callback_data = callback_data;
+}
+
+
+/* hi-level message hashing interface */
+
+/**
+ * Compute a hash of the given message.
+ *
+ * @param hash_id id of hash sum to compute
+ * @param message the message to process
+ * @param length message length
+ * @param result buffer to receive binary hash string
+ * @return 0 on success, -1 on error
+ */
+RHASH_API int rhash_msg(unsigned hash_id, const void* message, size_t length, unsigned char* result)
+{
+ rhash ctx;
+ hash_id &= RHASH_ALL_HASHES;
+ ctx = rhash_init(hash_id);
+ if (ctx == NULL) return -1;
+ rhash_update(ctx, message, length);
+ rhash_final(ctx, result);
+ rhash_free(ctx);
+ return 0;
+}
+
+/**
+ * Hash a file or stream. Multiple hashes can be computed.
+ * First, inintialize ctx parameter with rhash_init() before calling
+ * rhash_file_update(). Then use rhash_final() and rhash_print()
+ * to retrive hash values. Finaly call rhash_free() on ctx
+ * to free allocated memory or call rhash_reset() to reuse ctx.
+ *
+ * @param ctx rhash context
+ * @param fd descriptor of the file to hash
+ * @return 0 on success, -1 on error and errno is set
+ */
+RHASH_API int rhash_file_update(rhash ctx, FILE* fd)
+{
+ rhash_context_ext* const ectx = (rhash_context_ext*)ctx;
+ const size_t block_size = 8192;
+ unsigned char *buffer, *pmem;
+ size_t length = 0, align8;
+ int res = 0;
+ if (ectx->state != STATE_ACTIVE) return 0; /* do nothing if canceled */
+
+ if (ctx == NULL) {
+ errno = EINVAL;
+ return -1;
+ }
+
+ pmem = (unsigned char*)malloc(block_size + 8);
+ if (!pmem) return -1; /* errno is set to ENOMEM according to UNIX 98 */
+
+ align8 = ((unsigned char*)0 - pmem) & 7;
+ buffer = pmem + align8;
+
+ while (!feof(fd)) {
+ /* stop if canceled */
+ if (ectx->state != STATE_ACTIVE) break;
+
+ length = fread(buffer, 1, block_size, fd);
+
+ if (ferror(fd)) {
+ res = -1; /* note: errno contains error code */
+ break;
+ } else if (length) {
+ rhash_update(ctx, buffer, length);
+
+ if (ectx->callback) {
+ ((rhash_callback_t)ectx->callback)(ectx->callback_data, ectx->rc.msg_size);
+ }
+ }
+ }
+
+ free(buffer);
+ return res;
+}
+
+/**
+ * Compute a single hash for given file.
+ *
+ * @param hash_id id of hash sum to compute
+ * @param filepath path to the file to hash
+ * @param result buffer to receive hash value with the lowest requested id
+ * @return 0 on success, -1 on error and errno is set
+ */
+RHASH_API int rhash_file(unsigned hash_id, const char* filepath, unsigned char* result)
+{
+ FILE* fd;
+ rhash ctx;
+ int res;
+
+ hash_id &= RHASH_ALL_HASHES;
+ if (hash_id == 0) {
+ errno = EINVAL;
+ return -1;
+ }
+
+ if ((fd = fopen(filepath, "rb")) == NULL) return -1;
+
+ if ((ctx = rhash_init(hash_id)) == NULL) return -1;
+
+ res = rhash_file_update(ctx, fd); /* hash the file */
+ fclose(fd);
+
+ rhash_final(ctx, result);
+ rhash_free(ctx);
+ return res;
+}
+
+#ifdef _WIN32 /* windows only function */
+#include <share.h>
+
+/**
+ * Compute a single hash for given file.
+ *
+ * @param hash_id id of hash sum to compute
+ * @param filepath path to the file to hash
+ * @param result buffer to receive hash value with the lowest requested id
+ * @return 0 on success, -1 on error, -1 on error and errno is set
+ */
+RHASH_API int rhash_wfile(unsigned hash_id, const wchar_t* filepath, unsigned char* result)
+{
+ FILE* fd;
+ rhash ctx;
+ int res;
+
+ hash_id &= RHASH_ALL_HASHES;
+ if (hash_id == 0) {
+ errno = EINVAL;
+ return -1;
+ }
+
+ if ((fd = _wfsopen(filepath, L"rb", _SH_DENYWR)) == NULL) return -1;
+
+ if ((ctx = rhash_init(hash_id)) == NULL) return -1;
+
+ res = rhash_file_update(ctx, fd); /* hash the file */
+ fclose(fd);
+
+ rhash_final(ctx, result);
+ rhash_free(ctx);
+ return res;
+}
+#endif
+
+/* RHash information functions */
+
+/**
+ * Returns information about a hash function by its hash_id.
+ *
+ * @param hash_id the id of hash algorithm
+ * @return pointer to the rhash_info structure containing the information
+ */
+const rhash_info* rhash_info_by_id(unsigned hash_id)
+{
+ hash_id &= RHASH_ALL_HASHES;
+ /* check that only one bit is set */
+ if (hash_id != (hash_id & -(int)hash_id)) return NULL;
+ /* note: alternative condition is (hash_id == 0 || (hash_id & (hash_id - 1)) != 0) */
+ return rhash_info_table[rhash_ctz(hash_id)].info;
+}
+
+#if 0
+/**
+ * Detect default digest output format for given hash algorithm.
+ *
+ * @param hash_id the id of hash algorithm
+ * @return 1 for base32 format, 0 for hexadecimal
+ */
+RHASH_API int rhash_is_base32(unsigned hash_id)
+{
+ /* fast method is just to test a bit-mask */
+ return ((hash_id & (RHASH_TTH | RHASH_AICH)) != 0);
+}
+#endif
+
+/**
+ * Returns size of binary digest for given hash algorithm.
+ *
+ * @param hash_id the id of hash algorithm
+ * @return digest size in bytes
+ */
+RHASH_API int rhash_get_digest_size(unsigned hash_id)
+{
+ hash_id &= RHASH_ALL_HASHES;
+ if (hash_id == 0 || (hash_id & (hash_id - 1)) != 0) return -1;
+ return (int)rhash_info_table[rhash_ctz(hash_id)].info->digest_size;
+}
+
+/**
+ * Returns length of digest hash string in default output format.
+ *
+ * @param hash_id the id of hash algorithm
+ * @return the length of hash string
+ */
+RHASH_API int rhash_get_hash_length(unsigned hash_id)
+{
+ const rhash_info* info = rhash_info_by_id(hash_id);
+ return (int)(info ? (info->flags & F_BS32 ?
+ BASE32_LENGTH(info->digest_size) : info->digest_size * 2) : 0);
+}
+
+/**
+ * Returns a name of given hash algorithm.
+ *
+ * @param hash_id the id of hash algorithm
+ * @return algorithm name
+ */
+RHASH_API const char* rhash_get_name(unsigned hash_id)
+{
+ const rhash_info* info = rhash_info_by_id(hash_id);
+ return (info ? info->name : 0);
+}
+
+/**
+ * Returns a name part of magnet urn of the given hash algorithm.
+ * Such magnet_name is used to generate a magnet link of the form
+ * urn:&lt;magnet_name&gt;=&lt;hash_value&gt;.
+ *
+ * @param hash_id the id of hash algorithm
+ * @return name
+ */
+RHASH_API const char* rhash_get_magnet_name(unsigned hash_id)
+{
+ const rhash_info* info = rhash_info_by_id(hash_id);
+ return (info ? info->magnet_name : 0);
+}
+
+#if 0
+static size_t rhash_get_magnet_url_size(const char* filepath,
+ rhash context, unsigned hash_mask, int flags)
+{
+ size_t size = 0; /* count terminating '\0' */
+ unsigned bit, hash = context->hash_id & hash_mask;
+
+ /* RHPR_NO_MAGNET, RHPR_FILESIZE */
+ if ((flags & RHPR_NO_MAGNET) == 0) {
+ size += 8;
+ }
+
+ if ((flags & RHPR_FILESIZE) != 0) {
+ uint64_t num = context->msg_size;
+
+ size += 4;
+ if (num == 0) size++;
+ else {
+ for (; num; num /= 10, size++);
+ }
+ }
+
+ if (filepath) {
+ size += 4 + rhash_urlencode(NULL, filepath);
+ }
+
+ /* loop through hash values */
+ for (bit = hash & -(int)hash; bit <= hash; bit <<= 1) {
+ const char* name;
+ if ((bit & hash) == 0) continue;
+ if ((name = rhash_get_magnet_name(bit)) == 0) continue;
+
+ size += (7 + 2) + strlen(name);
+ size += rhash_print(NULL, context, bit,
+ (bit & (RHASH_SHA1 | RHASH_BTIH) ? RHPR_BASE32 : 0));
+ }
+
+ return size;
+}
+
+/**
+ * Print magnet link with given filepath and calculated hash sums into the
+ * output buffer. The hash_mask can limit which hash values will be printed.
+ * The function returns the size of the required buffer.
+ * If output is NULL the .
+ *
+ * @param output a string buffer to receive the magnet link or NULL
+ * @param filepath the file path to be printed or NULL
+ * @param context algorithms state
+ * @param hash_mask bit mask of the hash sums to add to the link
+ * @param flags can be combination of bits RHPR_UPPERCASE, RHPR_NO_MAGNET,
+ * RHPR_FILESIZE
+ * @return number of written characters, including terminating '\0' on success, 0 on fail
+ */
+RHASH_API size_t rhash_print_magnet(char* output, const char* filepath,
+ rhash context, unsigned hash_mask, int flags)
+{
+ int i;
+ const char* begin = output;
+
+ if (output == NULL) return rhash_get_magnet_url_size(
+ filepath, context, hash_mask, flags);
+
+ /* RHPR_NO_MAGNET, RHPR_FILESIZE */
+ if ((flags & RHPR_NO_MAGNET) == 0) {
+ strcpy(output, "magnet:?");
+ output += 8;
+ }
+
+ if ((flags & RHPR_FILESIZE) != 0) {
+ strcpy(output, "xl=");
+ output += 3;
+ output += rhash_sprintI64(output, context->msg_size);
+ *(output++) = '&';
+ }
+
+ if (filepath) {
+ strcpy(output, "dn=");
+ output += 3;
+ output += rhash_urlencode(output, filepath);
+ *(output++) = '&';
+ }
+ flags &= RHPR_UPPERCASE;
+
+ for (i = 0; i < 2; i++) {
+ unsigned bit;
+ unsigned hash = context->hash_id & hash_mask;
+ hash = (i == 0 ? hash & (RHASH_ED2K | RHASH_AICH)
+ : hash & ~(RHASH_ED2K | RHASH_AICH));
+ if (!hash) continue;
+
+ /* loop through hash values */
+ for (bit = hash & -(int)hash; bit <= hash; bit <<= 1) {
+ const char* name;
+ if ((bit & hash) == 0) continue;
+ if (!(name = rhash_get_magnet_name(bit))) continue;
+
+ strcpy(output, "xt=urn:");
+ output += 7;
+ strcpy(output, name);
+ output += strlen(name);
+ *(output++) = ':';
+ output += rhash_print(output, context, bit,
+ (bit & (RHASH_SHA1 | RHASH_BTIH) ? flags | RHPR_BASE32 : flags));
+ *(output++) = '&';
+ }
+ }
+ output[-1] = '\0'; /* terminate the line */
+
+ return (output - begin);
+}
+
+/* hash sum output */
+
+/**
+ * Print a text presentation of a given hash sum to the specified buffer,
+ *
+ * @param output a buffer to print the hash to
+ * @param bytes a hash sum to print
+ * @param size a size of hash sum in bytes
+ * @param flags a bit-mask controlling how to format the hash sum,
+ * can be a mix of the flags: RHPR_RAW, RHPR_HEX, RHPR_BASE32,
+ * RHPR_BASE64, RHPR_UPPERCASE, RHPR_REVERSE
+ * @return the number of written characters
+ */
+size_t rhash_print_bytes(char* output, const unsigned char* bytes,
+ size_t size, int flags)
+{
+ size_t str_len;
+ int upper_case = (flags & RHPR_UPPERCASE);
+ int format = (flags & ~RHPR_MODIFIER);
+
+ switch (format) {
+ case RHPR_HEX:
+ str_len = size * 2;
+ rhash_byte_to_hex(output, bytes, (unsigned)size, upper_case);
+ break;
+ case RHPR_BASE32:
+ str_len = BASE32_LENGTH(size);
+ rhash_byte_to_base32(output, bytes, (unsigned)size, upper_case);
+ break;
+ case RHPR_BASE64:
+ str_len = BASE64_LENGTH(size);
+ rhash_byte_to_base64(output, bytes, (unsigned)size);
+ break;
+ default:
+ str_len = size;
+ memcpy(output, bytes, size);
+ break;
+ }
+ return str_len;
+}
+
+/**
+ * Print text presentation of a hash sum with given hash_id to the specified
+ * output buffer. If the hash_id is zero, then print the hash sum with
+ * the lowest id stored in the hash context.
+ * The function call fails if the context doesn't include a hash with the
+ * given hash_id.
+ *
+ * @param output a buffer to print the hash to
+ * @param context algorithms state
+ * @param hash_id id of the hash sum to print or 0 to print the first hash
+ * saved in the context.
+ * @param flags a bitmask controlling how to print the hash. Can contain flags
+ * RHPR_UPPERCASE, RHPR_HEX, RHPR_BASE32, RHPR_BASE64, etc.
+ * @return the number of written characters on success or 0 on fail
+ */
+size_t RHASH_API rhash_print(char* output, rhash context, unsigned hash_id, int flags)
+{
+ const rhash_info* info;
+ unsigned char digest[80];
+ size_t digest_size;
+
+ info = (hash_id != 0 ? rhash_info_by_id(hash_id) :
+ ((rhash_context_ext*)context)->vector[0].hash_info->info);
+
+ if (info == NULL) return 0;
+ digest_size = info->digest_size;
+ assert(digest_size <= 64);
+
+ flags &= (RHPR_FORMAT | RHPR_MODIFIER);
+ if ((flags & RHPR_FORMAT) == 0) {
+ /* use default format if not specified by flags */
+ flags |= (info->flags & RHASH_INFO_BASE32 ? RHPR_BASE32 : RHPR_HEX);
+ }
+
+ if (output == NULL) {
+ switch (flags & RHPR_FORMAT) {
+ case RHPR_HEX:
+ return (digest_size * 2);
+ case RHPR_BASE32:
+ return BASE32_LENGTH(digest_size);
+ case RHPR_BASE64:
+ return BASE64_LENGTH(digest_size);
+ default:
+ return digest_size;
+ }
+ }
+
+ /* note: use info->hash_id, cause hash_id can be 0 */
+ rhash_put_digest(context, info->hash_id, digest);
+
+ if ((flags & ~RHPR_UPPERCASE) == (RHPR_REVERSE | RHPR_HEX)) {
+ /* reverse the digest */
+ unsigned char *p = digest, *r = digest + digest_size - 1;
+ char tmp;
+ for (; p < r; p++, r--) {
+ tmp = *p;
+ *p = *r;
+ *r = tmp;
+ }
+ }
+
+ return rhash_print_bytes(output, digest, digest_size, flags);
+}
+
+#if defined(_WIN32) && defined(RHASH_EXPORTS)
+#include <windows.h>
+BOOL APIENTRY DllMain(HMODULE hModule, DWORD reason, LPVOID reserved);
+BOOL APIENTRY DllMain(HMODULE hModule, DWORD reason, LPVOID reserved)
+{
+ (void)hModule;
+ (void)reserved;
+ switch (reason) {
+ case DLL_PROCESS_ATTACH:
+ rhash_library_init();
+ break;
+ case DLL_PROCESS_DETACH:
+ /*rhash_library_free();*/
+ case DLL_THREAD_ATTACH:
+ case DLL_THREAD_DETACH:
+ break;
+ }
+ return TRUE;
+}
+#endif
+
+#define PVOID2UPTR(p) ((rhash_uptr_t)((char*)p - 0))
+
+/**
+ * Process a rhash message.
+ *
+ * @param msg_id message identifier
+ * @param dst message destination (can be NULL for generic messages)
+ * @param ldata data depending on message
+ * @param rdata data depending on message
+ * @return message-specific data
+ */
+RHASH_API rhash_uptr_t rhash_transmit(unsigned msg_id, void* dst, rhash_uptr_t ldata, rhash_uptr_t rdata)
+{
+ /* for messages working with rhash context */
+ rhash_context_ext* const ctx = (rhash_context_ext*)dst;
+
+ switch (msg_id) {
+ case RMSG_GET_CONTEXT:
+ {
+ unsigned i;
+ for (i = 0; i < ctx->hash_vector_size; i++) {
+ struct rhash_hash_info* info = ctx->vector[i].hash_info;
+ if (info->info->hash_id == (unsigned)ldata)
+ return PVOID2UPTR(ctx->vector[i].context);
+ }
+ return (rhash_uptr_t)0;
+ }
+
+ case RMSG_CANCEL:
+ /* mark rhash context as canceled, in a multithreaded program */
+ atomic_compare_and_swap(&ctx->state, STATE_ACTIVE, STATE_STOPED);
+ return 0;
+
+ case RMSG_IS_CANCELED:
+ return (ctx->state == STATE_STOPED);
+
+ case RMSG_GET_FINALIZED:
+ return ((ctx->flags & RCTX_FINALIZED) != 0);
+ case RMSG_SET_AUTOFINAL:
+ ctx->flags &= ~RCTX_AUTO_FINAL;
+ if (ldata) ctx->flags |= RCTX_AUTO_FINAL;
+ break;
+
+ /* OpenSSL related messages */
+#ifdef USE_OPENSSL
+ case RMSG_SET_OPENSSL_MASK:
+ rhash_openssl_hash_mask = (unsigned)ldata;
+ break;
+ case RMSG_GET_OPENSSL_MASK:
+ return rhash_openssl_hash_mask;
+#endif
+
+ default:
+ return RHASH_ERROR; /* unknown message */
+ }
+ return 0;
+}
+#endif
diff --git a/Utilities/cmlibrhash/librhash/rhash.h b/Utilities/cmlibrhash/librhash/rhash.h
new file mode 100644
index 0000000..6d18c18
--- /dev/null
+++ b/Utilities/cmlibrhash/librhash/rhash.h
@@ -0,0 +1,280 @@
+/** @file rhash.h LibRHash interface */
+#ifndef RHASH_H
+#define RHASH_H
+
+#include <stdio.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef RHASH_API
+/* modifier for LibRHash functions */
+# define RHASH_API
+#endif
+
+/**
+ * Identifiers of supported hash functions.
+ * The rhash_init() function allows mixing several ids using
+ * binary OR, to calculate several hash functions for one message.
+ */
+enum rhash_ids
+{
+#if 0
+ RHASH_CRC32 = 0x01,
+ RHASH_MD4 = 0x02,
+ RHASH_MD5 = 0x04,
+ RHASH_SHA1 = 0x08,
+ RHASH_TIGER = 0x10,
+ RHASH_TTH = 0x20,
+ RHASH_BTIH = 0x40,
+ RHASH_ED2K = 0x80,
+ RHASH_AICH = 0x100,
+ RHASH_WHIRLPOOL = 0x200,
+ RHASH_RIPEMD160 = 0x400,
+ RHASH_GOST = 0x800,
+ RHASH_GOST_CRYPTOPRO = 0x1000,
+ RHASH_HAS160 = 0x2000,
+ RHASH_SNEFRU128 = 0x4000,
+ RHASH_SNEFRU256 = 0x8000,
+ RHASH_SHA224 = 0x10000,
+ RHASH_SHA256 = 0x20000,
+ RHASH_SHA384 = 0x40000,
+ RHASH_SHA512 = 0x80000,
+ RHASH_EDONR256 = 0x0100000,
+ RHASH_EDONR512 = 0x0200000,
+ RHASH_SHA3_224 = 0x0400000,
+ RHASH_SHA3_256 = 0x0800000,
+ RHASH_SHA3_384 = 0x1000000,
+ RHASH_SHA3_512 = 0x2000000,
+
+ /** The bit-mask containing all supported hashe functions */
+ RHASH_ALL_HASHES = RHASH_CRC32 | RHASH_MD4 | RHASH_MD5 | RHASH_ED2K | RHASH_SHA1 |
+ RHASH_TIGER | RHASH_TTH | RHASH_GOST | RHASH_GOST_CRYPTOPRO |
+ RHASH_BTIH | RHASH_AICH | RHASH_WHIRLPOOL | RHASH_RIPEMD160 |
+ RHASH_HAS160 | RHASH_SNEFRU128 | RHASH_SNEFRU256 |
+ RHASH_SHA224 | RHASH_SHA256 | RHASH_SHA384 | RHASH_SHA512 |
+ RHASH_SHA3_224 | RHASH_SHA3_256 | RHASH_SHA3_384 | RHASH_SHA3_512 |
+ RHASH_EDONR256 | RHASH_EDONR512,
+
+ /** The number of supported hash functions */
+ RHASH_HASH_COUNT = 26
+#else
+ RHASH_MD5 = 0x01,
+ RHASH_SHA1 = 0x02,
+ RHASH_SHA224 = 0x04,
+ RHASH_SHA256 = 0x08,
+ RHASH_SHA384 = 0x10,
+ RHASH_SHA512 = 0x20,
+ RHASH_ALL_HASHES =
+ RHASH_MD5 |
+ RHASH_SHA1 |
+ RHASH_SHA224 |
+ RHASH_SHA256 |
+ RHASH_SHA384 |
+ RHASH_SHA512,
+ RHASH_HASH_COUNT = 6
+#endif
+};
+
+/**
+ * The rhash context structure contains contexts for several hash functions
+ */
+typedef struct rhash_context
+{
+ /** The size of the hashed message */
+ unsigned long long msg_size;
+
+ /**
+ * The bit-mask containing identifiers of the hashes being calculated
+ */
+ unsigned hash_id;
+} rhash_context;
+
+#ifndef LIBRHASH_RHASH_CTX_DEFINED
+#define LIBRHASH_RHASH_CTX_DEFINED
+/**
+ * Hashing context.
+ */
+typedef struct rhash_context* rhash;
+#endif /* LIBRHASH_RHASH_CTX_DEFINED */
+
+/** type of a callback to be called periodically while hashing a file */
+typedef void (*rhash_callback_t)(void* data, unsigned long long offset);
+
+RHASH_API void rhash_library_init(void); /* initialize static data */
+
+/* hi-level hashing functions */
+RHASH_API int rhash_msg(unsigned hash_id, const void* message, size_t length, unsigned char* result);
+RHASH_API int rhash_file(unsigned hash_id, const char* filepath, unsigned char* result);
+RHASH_API int rhash_file_update(rhash ctx, FILE* fd);
+
+#ifdef _WIN32 /* windows only function */
+RHASH_API int rhash_wfile(unsigned hash_id, const wchar_t* filepath, unsigned char* result);
+#endif
+
+/* lo-level interface */
+RHASH_API rhash rhash_init(unsigned hash_id);
+/*RHASH_API rhash rhash_init_by_ids(unsigned hash_ids[], unsigned count);*/
+RHASH_API int rhash_update(rhash ctx, const void* message, size_t length);
+RHASH_API int rhash_final(rhash ctx, unsigned char* first_result);
+RHASH_API void rhash_reset(rhash ctx); /* reinitialize the context */
+RHASH_API void rhash_free(rhash ctx);
+
+/* additional lo-level functions */
+RHASH_API void rhash_set_callback(rhash ctx, rhash_callback_t callback, void* callback_data);
+
+/** bit-flag: default hash output format is base32 */
+#define RHASH_INFO_BASE32 1
+
+/**
+ * Information about a hash function.
+ */
+typedef struct rhash_info
+{
+ /** hash function indentifier */
+ unsigned hash_id;
+ /** flags bit-mask, including RHASH_INFO_BASE32 bit */
+ unsigned flags;
+ /** size of binary message digest in bytes */
+ size_t digest_size;
+ const char* name;
+ const char* magnet_name;
+} rhash_info;
+
+/* information functions */
+RHASH_API int rhash_count(void); /* number of supported hashes */
+RHASH_API int rhash_get_digest_size(unsigned hash_id); /* size of binary message digest */
+RHASH_API int rhash_get_hash_length(unsigned hash_id); /* length of formated hash string */
+RHASH_API int rhash_is_base32(unsigned hash_id); /* default digest output format */
+RHASH_API const char* rhash_get_name(unsigned hash_id); /* get hash function name */
+RHASH_API const char* rhash_get_magnet_name(unsigned hash_id); /* get name part of magnet urn */
+
+/* note, that rhash_info_by_id() is not exported to a shared library or DLL */
+const rhash_info* rhash_info_by_id(unsigned hash_id); /* get hash sum info by hash id */
+
+#if 0
+/**
+ * Flags for printing a hash sum
+ */
+enum rhash_print_sum_flags
+{
+ /** print in a default format */
+ RHPR_DEFAULT = 0x0,
+ /** output as binary message digest */
+ RHPR_RAW = 0x1,
+ /** print as a hexadecimal string */
+ RHPR_HEX = 0x2,
+ /** print as a base32-encoded string */
+ RHPR_BASE32 = 0x3,
+ /** print as a base64-encoded string */
+ RHPR_BASE64 = 0x4,
+
+ /**
+ * Print as an uppercase string. Can be used
+ * for base32 or hexadecimal format only.
+ */
+ RHPR_UPPERCASE = 0x8,
+
+ /**
+ * Reverse hash bytes. Can be used for GOST hash.
+ */
+ RHPR_REVERSE = 0x10,
+
+ /** don't print 'magnet:?' prefix in rhash_print_magnet */
+ RHPR_NO_MAGNET = 0x20,
+ /** print file size in rhash_print_magnet */
+ RHPR_FILESIZE = 0x40,
+};
+#endif
+
+/* output hash into the given buffer */
+RHASH_API size_t rhash_print_bytes(char* output,
+ const unsigned char* bytes, size_t size, int flags);
+
+RHASH_API size_t rhash_print(char* output, rhash ctx, unsigned hash_id,
+ int flags);
+
+/* output magnet URL into the given buffer */
+RHASH_API size_t rhash_print_magnet(char* output, const char* filepath,
+ rhash context, unsigned hash_mask, int flags);
+
+/* macros for message API */
+
+/** The type of an unsigned integer large enough to hold a pointer */
+#if defined(UINTPTR_MAX)
+typedef uintptr_t rhash_uptr_t;
+#elif defined(_LP64) || defined(__LP64__) || defined(__x86_64) || \
+ defined(__x86_64__) || defined(_M_AMD64) || defined(_M_X64)
+typedef unsigned long long rhash_uptr_t;
+#else
+typedef unsigned long rhash_uptr_t;
+#endif
+
+/** The value returned by rhash_transmit on error */
+#define RHASH_ERROR ((rhash_uptr_t)-1)
+/** Convert a pointer to rhash_uptr_t */
+#define RHASH_STR2UPTR(str) ((rhash_uptr_t)(char*)(str))
+/** Convert a rhash_uptr_t to a void* pointer */
+#define RHASH_UPTR2PVOID(u) ((void*)((char*)0 + (u)))
+
+/* rhash API to set/get data via messages */
+RHASH_API rhash_uptr_t rhash_transmit(
+ unsigned msg_id, void* dst, rhash_uptr_t ldata, rhash_uptr_t rdata);
+
+/* rhash message constants */
+
+#define RMSG_GET_CONTEXT 1
+#define RMSG_CANCEL 2
+#define RMSG_IS_CANCELED 3
+#define RMSG_GET_FINALIZED 4
+#define RMSG_SET_AUTOFINAL 5
+#define RMSG_SET_OPENSSL_MASK 10
+#define RMSG_GET_OPENSSL_MASK 11
+
+/* helper macros */
+
+/** Get a pointer to context of the specified hash function */
+#define rhash_get_context_ptr(ctx, hash_id) RHASH_UPTR2PVOID(rhash_transmit(RMSG_GET_CONTEXT, ctx, hash_id, 0))
+/** Cancel hash calculation of a file */
+#define rhash_cancel(ctx) rhash_transmit(RMSG_CANCEL, ctx, 0, 0)
+/** Return non-zero if hash calculation was canceled, zero otherwise */
+#define rhash_is_canceled(ctx) rhash_transmit(RMSG_IS_CANCELED, ctx, 0, 0)
+/** Return non-zero if rhash_final was called for rhash_context */
+#define rhash_get_finalized(ctx) rhash_transmit(RMSG_GET_FINALIZED, ctx, 0, 0)
+
+/**
+ * Turn on/off the auto-final flag for the given rhash_context. By default
+ * auto-final is on, which means rhash_final is called automatically, if
+ * needed when a hash value is retrived by rhash_print call.
+ */
+#define rhash_set_autofinal(ctx, on) rhash_transmit(RMSG_SET_AUTOFINAL, ctx, on, 0)
+
+/**
+ * Set the bit-mask of hash algorithms to be calculated by OpenSSL library.
+ * The call rhash_set_openssl_mask(0) made before rhash_library_init(),
+ * turns off loading of the OpenSSL dynamic library.
+ * This call works if the LibRHash was compiled with OpenSSL support.
+ */
+#define rhash_set_openssl_mask(mask) rhash_transmit(RMSG_SET_OPENSSL_MASK, NULL, mask, 0)
+
+/**
+ * Return current bit-mask of hash algorithms selected to be calculated
+ * by OpenSSL library.
+ */
+#define rhash_get_openssl_mask() rhash_transmit(RMSG_GET_OPENSSL_MASK, NULL, 0, 0)
+
+/** The bit mask of hash algorithms implemented by OpenSSL */
+#if defined(USE_OPENSSL) || defined(OPENSSL_RUNTIME)
+# define RHASH_OPENSSL_SUPPORTED_HASHES (RHASH_MD4 | RHASH_MD5 | \
+ RHASH_SHA1 | RHASH_SHA224 | RHASH_SHA256 | RHASH_SHA384 | \
+ RHASH_SHA512 | RHASH_RIPEMD160 | RHASH_WHIRLPOOL)
+#else
+# define RHASH_OPENSSL_SUPPORTED_HASHES 0
+#endif
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif /* __cplusplus */
+
+#endif /* RHASH_H */
diff --git a/Utilities/cmlibrhash/librhash/sha1.c b/Utilities/cmlibrhash/librhash/sha1.c
new file mode 100644
index 0000000..f5a053b
--- /dev/null
+++ b/Utilities/cmlibrhash/librhash/sha1.c
@@ -0,0 +1,196 @@
+/* sha1.c - an implementation of Secure Hash Algorithm 1 (SHA1)
+ * based on RFC 3174.
+ *
+ * Copyright: 2008-2012 Aleksey Kravchenko <rhash.admin@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. Use this program at your own risk!
+ */
+
+#include <string.h>
+#include "byte_order.h"
+#include "sha1.h"
+
+/**
+ * Initialize context before calculaing hash.
+ *
+ * @param ctx context to initialize
+ */
+void rhash_sha1_init(sha1_ctx *ctx)
+{
+ ctx->length = 0;
+
+ /* initialize algorithm state */
+ ctx->hash[0] = 0x67452301;
+ ctx->hash[1] = 0xefcdab89;
+ ctx->hash[2] = 0x98badcfe;
+ ctx->hash[3] = 0x10325476;
+ ctx->hash[4] = 0xc3d2e1f0;
+}
+
+/**
+ * The core transformation. Process a 512-bit block.
+ * The function has been taken from RFC 3174 with little changes.
+ *
+ * @param hash algorithm state
+ * @param block the message block to process
+ */
+static void rhash_sha1_process_block(unsigned* hash, const unsigned* block)
+{
+ int t; /* Loop counter */
+ uint32_t temp; /* Temporary word value */
+ uint32_t W[80]; /* Word sequence */
+ uint32_t A, B, C, D, E; /* Word buffers */
+
+ /* initialize the first 16 words in the array W */
+ for (t = 0; t < 16; t++) {
+ /* note: it is much faster to apply be2me here, then using be32_copy */
+ W[t] = be2me_32(block[t]);
+ }
+
+ /* initialize the rest */
+ for (t = 16; t < 80; t++) {
+ W[t] = ROTL32(W[t - 3] ^ W[t - 8] ^ W[t - 14] ^ W[t - 16], 1);
+ }
+
+ A = hash[0];
+ B = hash[1];
+ C = hash[2];
+ D = hash[3];
+ E = hash[4];
+
+ for (t = 0; t < 20; t++) {
+ /* the following is faster than ((B & C) | ((~B) & D)) */
+ temp = ROTL32(A, 5) + (((C ^ D) & B) ^ D)
+ + E + W[t] + 0x5A827999;
+ E = D;
+ D = C;
+ C = ROTL32(B, 30);
+ B = A;
+ A = temp;
+ }
+
+ for (t = 20; t < 40; t++) {
+ temp = ROTL32(A, 5) + (B ^ C ^ D) + E + W[t] + 0x6ED9EBA1;
+ E = D;
+ D = C;
+ C = ROTL32(B, 30);
+ B = A;
+ A = temp;
+ }
+
+ for (t = 40; t < 60; t++) {
+ temp = ROTL32(A, 5) + ((B & C) | (B & D) | (C & D))
+ + E + W[t] + 0x8F1BBCDC;
+ E = D;
+ D = C;
+ C = ROTL32(B, 30);
+ B = A;
+ A = temp;
+ }
+
+ for (t = 60; t < 80; t++) {
+ temp = ROTL32(A, 5) + (B ^ C ^ D) + E + W[t] + 0xCA62C1D6;
+ E = D;
+ D = C;
+ C = ROTL32(B, 30);
+ B = A;
+ A = temp;
+ }
+
+ hash[0] += A;
+ hash[1] += B;
+ hash[2] += C;
+ hash[3] += D;
+ hash[4] += E;
+}
+
+/**
+ * Calculate message hash.
+ * Can be called repeatedly with chunks of the message to be hashed.
+ *
+ * @param ctx the algorithm context containing current hashing state
+ * @param msg message chunk
+ * @param size length of the message chunk
+ */
+void rhash_sha1_update(sha1_ctx *ctx, const unsigned char* msg, size_t size)
+{
+ unsigned index = (unsigned)ctx->length & 63;
+ ctx->length += size;
+
+ /* fill partial block */
+ if (index) {
+ unsigned left = sha1_block_size - index;
+ memcpy(ctx->message + index, msg, (size < left ? size : left));
+ if (size < left) return;
+
+ /* process partial block */
+ rhash_sha1_process_block(ctx->hash, (unsigned*)ctx->message);
+ msg += left;
+ size -= left;
+ }
+ while (size >= sha1_block_size) {
+ unsigned* aligned_message_block;
+ if (IS_ALIGNED_32(msg)) {
+ /* the most common case is processing of an already aligned message
+ without copying it */
+ aligned_message_block = (unsigned*)msg;
+ } else {
+ memcpy(ctx->message, msg, sha1_block_size);
+ aligned_message_block = (unsigned*)ctx->message;
+ }
+
+ rhash_sha1_process_block(ctx->hash, aligned_message_block);
+ msg += sha1_block_size;
+ size -= sha1_block_size;
+ }
+ if (size) {
+ /* save leftovers */
+ memcpy(ctx->message, msg, size);
+ }
+}
+
+/**
+ * Store calculated hash into the given array.
+ *
+ * @param ctx the algorithm context containing current hashing state
+ * @param result calculated hash in binary form
+ */
+void rhash_sha1_final(sha1_ctx *ctx, unsigned char* result)
+{
+ unsigned index = (unsigned)ctx->length & 63;
+ unsigned* msg32 = (unsigned*)ctx->message;
+
+ /* pad message and run for last block */
+ ctx->message[index++] = 0x80;
+ while ((index & 3) != 0) {
+ ctx->message[index++] = 0;
+ }
+ index >>= 2;
+
+ /* if no room left in the message to store 64-bit message length */
+ if (index > 14) {
+ /* then fill the rest with zeros and process it */
+ while (index < 16) {
+ msg32[index++] = 0;
+ }
+ rhash_sha1_process_block(ctx->hash, msg32);
+ index = 0;
+ }
+ while (index < 14) {
+ msg32[index++] = 0;
+ }
+ msg32[14] = be2me_32( (unsigned)(ctx->length >> 29) );
+ msg32[15] = be2me_32( (unsigned)(ctx->length << 3) );
+ rhash_sha1_process_block(ctx->hash, msg32);
+
+ if (result) be32_copy(result, 0, &ctx->hash, sha1_hash_size);
+}
diff --git a/Utilities/cmlibrhash/librhash/sha1.h b/Utilities/cmlibrhash/librhash/sha1.h
new file mode 100644
index 0000000..74b2f94
--- /dev/null
+++ b/Utilities/cmlibrhash/librhash/sha1.h
@@ -0,0 +1,31 @@
+/* sha1.h */
+#ifndef SHA1_H
+#define SHA1_H
+#include "ustd.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define sha1_block_size 64
+#define sha1_hash_size 20
+
+/* algorithm context */
+typedef struct sha1_ctx
+{
+ unsigned char message[sha1_block_size]; /* 512-bit buffer for leftovers */
+ uint64_t length; /* number of processed bytes */
+ unsigned hash[5]; /* 160-bit algorithm internal hashing state */
+} sha1_ctx;
+
+/* hash functions */
+
+void rhash_sha1_init(sha1_ctx *ctx);
+void rhash_sha1_update(sha1_ctx *ctx, const unsigned char* msg, size_t size);
+void rhash_sha1_final(sha1_ctx *ctx, unsigned char* result);
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif /* __cplusplus */
+
+#endif /* SHA1_H */
diff --git a/Utilities/cmlibrhash/librhash/sha256.c b/Utilities/cmlibrhash/librhash/sha256.c
new file mode 100644
index 0000000..064dfe2
--- /dev/null
+++ b/Utilities/cmlibrhash/librhash/sha256.c
@@ -0,0 +1,241 @@
+/* sha256.c - an implementation of SHA-256/224 hash functions
+ * based on FIPS 180-3 (Federal Information Processing Standart).
+ *
+ * Copyright: 2010-2012 Aleksey Kravchenko <rhash.admin@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. Use this program at your own risk!
+ */
+
+#include <string.h>
+#include "byte_order.h"
+#include "sha256.h"
+
+/* SHA-224 and SHA-256 constants for 64 rounds. These words represent
+ * the first 32 bits of the fractional parts of the cube
+ * roots of the first 64 prime numbers. */
+static const unsigned rhash_k256[64] = {
+ 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1,
+ 0x923f82a4, 0xab1c5ed5, 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
+ 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, 0xe49b69c1, 0xefbe4786,
+ 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
+ 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147,
+ 0x06ca6351, 0x14292967, 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
+ 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, 0xa2bfe8a1, 0xa81a664b,
+ 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
+ 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a,
+ 0x5b9cca4f, 0x682e6ff3, 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
+ 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
+};
+
+/* The SHA256/224 functions defined by FIPS 180-3, 4.1.2 */
+/* Optimized version of Ch(x,y,z)=((x & y) | (~x & z)) */
+#define Ch(x,y,z) ((z) ^ ((x) & ((y) ^ (z))))
+/* Optimized version of Maj(x,y,z)=((x & y) ^ (x & z) ^ (y & z)) */
+#define Maj(x,y,z) (((x) & (y)) ^ ((z) & ((x) ^ (y))))
+
+#define Sigma0(x) (ROTR32((x), 2) ^ ROTR32((x), 13) ^ ROTR32((x), 22))
+#define Sigma1(x) (ROTR32((x), 6) ^ ROTR32((x), 11) ^ ROTR32((x), 25))
+#define sigma0(x) (ROTR32((x), 7) ^ ROTR32((x), 18) ^ ((x) >> 3))
+#define sigma1(x) (ROTR32((x),17) ^ ROTR32((x), 19) ^ ((x) >> 10))
+
+/* Recalculate element n-th of circular buffer W using formula
+ * W[n] = sigma1(W[n - 2]) + W[n - 7] + sigma0(W[n - 15]) + W[n - 16]; */
+#define RECALCULATE_W(W,n) (W[n] += \
+ (sigma1(W[(n - 2) & 15]) + W[(n - 7) & 15] + sigma0(W[(n - 15) & 15])))
+
+#define ROUND(a,b,c,d,e,f,g,h,k,data) { \
+ unsigned T1 = h + Sigma1(e) + Ch(e,f,g) + k + (data); \
+ d += T1, h = T1 + Sigma0(a) + Maj(a,b,c); }
+#define ROUND_1_16(a,b,c,d,e,f,g,h,n) \
+ ROUND(a,b,c,d,e,f,g,h, rhash_k256[n], W[n] = be2me_32(block[n]))
+#define ROUND_17_64(a,b,c,d,e,f,g,h,n) \
+ ROUND(a,b,c,d,e,f,g,h, k[n], RECALCULATE_W(W, n))
+
+/**
+ * Initialize context before calculaing hash.
+ *
+ * @param ctx context to initialize
+ */
+void rhash_sha256_init(sha256_ctx *ctx)
+{
+ /* Initial values. These words were obtained by taking the first 32
+ * bits of the fractional parts of the square roots of the first
+ * eight prime numbers. */
+ static const unsigned SHA256_H0[8] = {
+ 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a,
+ 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19
+ };
+
+ ctx->length = 0;
+ ctx->digest_length = sha256_hash_size;
+
+ /* initialize algorithm state */
+ memcpy(ctx->hash, SHA256_H0, sizeof(ctx->hash));
+}
+
+/**
+ * Initialize context before calculaing hash.
+ *
+ * @param ctx context to initialize
+ */
+void rhash_sha224_init(struct sha256_ctx *ctx)
+{
+ /* Initial values from FIPS 180-3. These words were obtained by taking
+ * bits from 33th to 64th of the fractional parts of the square
+ * roots of ninth through sixteenth prime numbers. */
+ static const unsigned SHA224_H0[8] = {
+ 0xc1059ed8, 0x367cd507, 0x3070dd17, 0xf70e5939,
+ 0xffc00b31, 0x68581511, 0x64f98fa7, 0xbefa4fa4
+ };
+
+ ctx->length = 0;
+ ctx->digest_length = sha224_hash_size;
+
+ memcpy(ctx->hash, SHA224_H0, sizeof(ctx->hash));
+}
+
+/**
+ * The core transformation. Process a 512-bit block.
+ *
+ * @param hash algorithm state
+ * @param block the message block to process
+ */
+static void rhash_sha256_process_block(unsigned hash[8], unsigned block[16])
+{
+ unsigned A, B, C, D, E, F, G, H;
+ unsigned W[16];
+ const unsigned *k;
+ int i;
+
+ A = hash[0], B = hash[1], C = hash[2], D = hash[3];
+ E = hash[4], F = hash[5], G = hash[6], H = hash[7];
+
+ /* Compute SHA using alternate Method: FIPS 180-3 6.1.3 */
+ ROUND_1_16(A, B, C, D, E, F, G, H, 0);
+ ROUND_1_16(H, A, B, C, D, E, F, G, 1);
+ ROUND_1_16(G, H, A, B, C, D, E, F, 2);
+ ROUND_1_16(F, G, H, A, B, C, D, E, 3);
+ ROUND_1_16(E, F, G, H, A, B, C, D, 4);
+ ROUND_1_16(D, E, F, G, H, A, B, C, 5);
+ ROUND_1_16(C, D, E, F, G, H, A, B, 6);
+ ROUND_1_16(B, C, D, E, F, G, H, A, 7);
+ ROUND_1_16(A, B, C, D, E, F, G, H, 8);
+ ROUND_1_16(H, A, B, C, D, E, F, G, 9);
+ ROUND_1_16(G, H, A, B, C, D, E, F, 10);
+ ROUND_1_16(F, G, H, A, B, C, D, E, 11);
+ ROUND_1_16(E, F, G, H, A, B, C, D, 12);
+ ROUND_1_16(D, E, F, G, H, A, B, C, 13);
+ ROUND_1_16(C, D, E, F, G, H, A, B, 14);
+ ROUND_1_16(B, C, D, E, F, G, H, A, 15);
+
+ for (i = 16, k = &rhash_k256[16]; i < 64; i += 16, k += 16) {
+ ROUND_17_64(A, B, C, D, E, F, G, H, 0);
+ ROUND_17_64(H, A, B, C, D, E, F, G, 1);
+ ROUND_17_64(G, H, A, B, C, D, E, F, 2);
+ ROUND_17_64(F, G, H, A, B, C, D, E, 3);
+ ROUND_17_64(E, F, G, H, A, B, C, D, 4);
+ ROUND_17_64(D, E, F, G, H, A, B, C, 5);
+ ROUND_17_64(C, D, E, F, G, H, A, B, 6);
+ ROUND_17_64(B, C, D, E, F, G, H, A, 7);
+ ROUND_17_64(A, B, C, D, E, F, G, H, 8);
+ ROUND_17_64(H, A, B, C, D, E, F, G, 9);
+ ROUND_17_64(G, H, A, B, C, D, E, F, 10);
+ ROUND_17_64(F, G, H, A, B, C, D, E, 11);
+ ROUND_17_64(E, F, G, H, A, B, C, D, 12);
+ ROUND_17_64(D, E, F, G, H, A, B, C, 13);
+ ROUND_17_64(C, D, E, F, G, H, A, B, 14);
+ ROUND_17_64(B, C, D, E, F, G, H, A, 15);
+ }
+
+ hash[0] += A, hash[1] += B, hash[2] += C, hash[3] += D;
+ hash[4] += E, hash[5] += F, hash[6] += G, hash[7] += H;
+}
+
+/**
+ * Calculate message hash.
+ * Can be called repeatedly with chunks of the message to be hashed.
+ *
+ * @param ctx the algorithm context containing current hashing state
+ * @param msg message chunk
+ * @param size length of the message chunk
+ */
+void rhash_sha256_update(sha256_ctx *ctx, const unsigned char *msg, size_t size)
+{
+ size_t index = (size_t)ctx->length & 63;
+ ctx->length += size;
+
+ /* fill partial block */
+ if (index) {
+ size_t left = sha256_block_size - index;
+ memcpy((char*)ctx->message + index, msg, (size < left ? size : left));
+ if (size < left) return;
+
+ /* process partial block */
+ rhash_sha256_process_block(ctx->hash, (unsigned*)ctx->message);
+ msg += left;
+ size -= left;
+ }
+ while (size >= sha256_block_size) {
+ unsigned* aligned_message_block;
+ if (IS_ALIGNED_32(msg)) {
+ /* the most common case is processing of an already aligned message
+ without copying it */
+ aligned_message_block = (unsigned*)msg;
+ } else {
+ memcpy(ctx->message, msg, sha256_block_size);
+ aligned_message_block = (unsigned*)ctx->message;
+ }
+
+ rhash_sha256_process_block(ctx->hash, aligned_message_block);
+ msg += sha256_block_size;
+ size -= sha256_block_size;
+ }
+ if (size) {
+ memcpy(ctx->message, msg, size); /* save leftovers */
+ }
+}
+
+/**
+ * Store calculated hash into the given array.
+ *
+ * @param ctx the algorithm context containing current hashing state
+ * @param result calculated hash in binary form
+ */
+void rhash_sha256_final(sha256_ctx *ctx, unsigned char* result)
+{
+ size_t index = ((unsigned)ctx->length & 63) >> 2;
+ unsigned shift = ((unsigned)ctx->length & 3) * 8;
+
+ /* pad message and run for last block */
+
+ /* append the byte 0x80 to the message */
+ ctx->message[index] &= le2me_32(~(0xFFFFFFFF << shift));
+ ctx->message[index++] ^= le2me_32(0x80 << shift);
+
+ /* if no room left in the message to store 64-bit message length */
+ if (index > 14) {
+ /* then fill the rest with zeros and process it */
+ while (index < 16) {
+ ctx->message[index++] = 0;
+ }
+ rhash_sha256_process_block(ctx->hash, ctx->message);
+ index = 0;
+ }
+ while (index < 14) {
+ ctx->message[index++] = 0;
+ }
+ ctx->message[14] = be2me_32( (unsigned)(ctx->length >> 29) );
+ ctx->message[15] = be2me_32( (unsigned)(ctx->length << 3) );
+ rhash_sha256_process_block(ctx->hash, ctx->message);
+
+ if (result) be32_copy(result, 0, ctx->hash, ctx->digest_length);
+}
diff --git a/Utilities/cmlibrhash/librhash/sha256.h b/Utilities/cmlibrhash/librhash/sha256.h
new file mode 100644
index 0000000..f87ebaa
--- /dev/null
+++ b/Utilities/cmlibrhash/librhash/sha256.h
@@ -0,0 +1,32 @@
+/* sha.h sha256 and sha224 hash functions */
+#ifndef SHA256_H
+#define SHA256_H
+#include "ustd.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define sha256_block_size 64
+#define sha256_hash_size 32
+#define sha224_hash_size 28
+
+/* algorithm context */
+typedef struct sha256_ctx
+{
+ unsigned message[16]; /* 512-bit buffer for leftovers */
+ uint64_t length; /* number of processed bytes */
+ unsigned hash[8]; /* 256-bit algorithm internal hashing state */
+ unsigned digest_length; /* length of the algorithm digest in bytes */
+} sha256_ctx;
+
+void rhash_sha224_init(sha256_ctx *ctx);
+void rhash_sha256_init(sha256_ctx *ctx);
+void rhash_sha256_update(sha256_ctx *ctx, const unsigned char* data, size_t length);
+void rhash_sha256_final(sha256_ctx *ctx, unsigned char result[32]);
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif /* __cplusplus */
+
+#endif /* SHA256_H */
diff --git a/Utilities/cmlibrhash/librhash/sha512.c b/Utilities/cmlibrhash/librhash/sha512.c
new file mode 100644
index 0000000..a3e681d
--- /dev/null
+++ b/Utilities/cmlibrhash/librhash/sha512.c
@@ -0,0 +1,255 @@
+/* sha512.c - an implementation of SHA-384/512 hash functions
+ * based on FIPS 180-3 (Federal Information Processing Standart).
+ *
+ * Copyright: 2010-2012 Aleksey Kravchenko <rhash.admin@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. Use this program at your own risk!
+ */
+
+#include <string.h>
+#include "byte_order.h"
+#include "sha512.h"
+
+/* SHA-384 and SHA-512 constants for 80 rounds. These qwords represent
+ * the first 64 bits of the fractional parts of the cube
+ * roots of the first 80 prime numbers. */
+static const uint64_t rhash_k512[80] = {
+ I64(0x428a2f98d728ae22), I64(0x7137449123ef65cd), I64(0xb5c0fbcfec4d3b2f),
+ I64(0xe9b5dba58189dbbc), I64(0x3956c25bf348b538), I64(0x59f111f1b605d019),
+ I64(0x923f82a4af194f9b), I64(0xab1c5ed5da6d8118), I64(0xd807aa98a3030242),
+ I64(0x12835b0145706fbe), I64(0x243185be4ee4b28c), I64(0x550c7dc3d5ffb4e2),
+ I64(0x72be5d74f27b896f), I64(0x80deb1fe3b1696b1), I64(0x9bdc06a725c71235),
+ I64(0xc19bf174cf692694), I64(0xe49b69c19ef14ad2), I64(0xefbe4786384f25e3),
+ I64(0x0fc19dc68b8cd5b5), I64(0x240ca1cc77ac9c65), I64(0x2de92c6f592b0275),
+ I64(0x4a7484aa6ea6e483), I64(0x5cb0a9dcbd41fbd4), I64(0x76f988da831153b5),
+ I64(0x983e5152ee66dfab), I64(0xa831c66d2db43210), I64(0xb00327c898fb213f),
+ I64(0xbf597fc7beef0ee4), I64(0xc6e00bf33da88fc2), I64(0xd5a79147930aa725),
+ I64(0x06ca6351e003826f), I64(0x142929670a0e6e70), I64(0x27b70a8546d22ffc),
+ I64(0x2e1b21385c26c926), I64(0x4d2c6dfc5ac42aed), I64(0x53380d139d95b3df),
+ I64(0x650a73548baf63de), I64(0x766a0abb3c77b2a8), I64(0x81c2c92e47edaee6),
+ I64(0x92722c851482353b), I64(0xa2bfe8a14cf10364), I64(0xa81a664bbc423001),
+ I64(0xc24b8b70d0f89791), I64(0xc76c51a30654be30), I64(0xd192e819d6ef5218),
+ I64(0xd69906245565a910), I64(0xf40e35855771202a), I64(0x106aa07032bbd1b8),
+ I64(0x19a4c116b8d2d0c8), I64(0x1e376c085141ab53), I64(0x2748774cdf8eeb99),
+ I64(0x34b0bcb5e19b48a8), I64(0x391c0cb3c5c95a63), I64(0x4ed8aa4ae3418acb),
+ I64(0x5b9cca4f7763e373), I64(0x682e6ff3d6b2b8a3), I64(0x748f82ee5defb2fc),
+ I64(0x78a5636f43172f60), I64(0x84c87814a1f0ab72), I64(0x8cc702081a6439ec),
+ I64(0x90befffa23631e28), I64(0xa4506cebde82bde9), I64(0xbef9a3f7b2c67915),
+ I64(0xc67178f2e372532b), I64(0xca273eceea26619c), I64(0xd186b8c721c0c207),
+ I64(0xeada7dd6cde0eb1e), I64(0xf57d4f7fee6ed178), I64(0x06f067aa72176fba),
+ I64(0x0a637dc5a2c898a6), I64(0x113f9804bef90dae), I64(0x1b710b35131c471b),
+ I64(0x28db77f523047d84), I64(0x32caab7b40c72493), I64(0x3c9ebe0a15c9bebc),
+ I64(0x431d67c49c100d4c), I64(0x4cc5d4becb3e42b6), I64(0x597f299cfc657e2a),
+ I64(0x5fcb6fab3ad6faec), I64(0x6c44198c4a475817)
+};
+
+/* The SHA512/384 functions defined by FIPS 180-3, 4.1.3 */
+/* Optimized version of Ch(x,y,z)=((x & y) | (~x & z)) */
+#define Ch(x,y,z) ((z) ^ ((x) & ((y) ^ (z))))
+/* Optimized version of Maj(x,y,z)=((x & y) ^ (x & z) ^ (y & z)) */
+#define Maj(x,y,z) (((x) & (y)) ^ ((z) & ((x) ^ (y))))
+
+#define Sigma0(x) (ROTR64((x), 28) ^ ROTR64((x), 34) ^ ROTR64((x), 39))
+#define Sigma1(x) (ROTR64((x), 14) ^ ROTR64((x), 18) ^ ROTR64((x), 41))
+#define sigma0(x) (ROTR64((x), 1) ^ ROTR64((x), 8) ^ ((x) >> 7))
+#define sigma1(x) (ROTR64((x), 19) ^ ROTR64((x), 61) ^ ((x) >> 6))
+
+/* Recalculate element n-th of circular buffer W using formula
+ * W[n] = sigma1(W[n - 2]) + W[n - 7] + sigma0(W[n - 15]) + W[n - 16]; */
+#define RECALCULATE_W(W,n) (W[n] += \
+ (sigma1(W[(n - 2) & 15]) + W[(n - 7) & 15] + sigma0(W[(n - 15) & 15])))
+
+#define ROUND(a,b,c,d,e,f,g,h,k,data) { \
+ uint64_t T1 = h + Sigma1(e) + Ch(e,f,g) + k + (data); \
+ d += T1, h = T1 + Sigma0(a) + Maj(a,b,c); }
+#define ROUND_1_16(a,b,c,d,e,f,g,h,n) \
+ ROUND(a,b,c,d,e,f,g,h, rhash_k512[n], W[n] = be2me_64(block[n]))
+#define ROUND_17_80(a,b,c,d,e,f,g,h,n) \
+ ROUND(a,b,c,d,e,f,g,h, k[n], RECALCULATE_W(W, n))
+
+/**
+ * Initialize context before calculating hash.
+ *
+ * @param ctx context to initialize
+ */
+void rhash_sha512_init(sha512_ctx *ctx)
+{
+ /* Initial values. These words were obtained by taking the first 32
+ * bits of the fractional parts of the square roots of the first
+ * eight prime numbers. */
+ static const uint64_t SHA512_H0[8] = {
+ I64(0x6a09e667f3bcc908), I64(0xbb67ae8584caa73b), I64(0x3c6ef372fe94f82b),
+ I64(0xa54ff53a5f1d36f1), I64(0x510e527fade682d1), I64(0x9b05688c2b3e6c1f),
+ I64(0x1f83d9abfb41bd6b), I64(0x5be0cd19137e2179)
+ };
+
+ ctx->length = 0;
+ ctx->digest_length = sha512_hash_size;
+
+ /* initialize algorithm state */
+ memcpy(ctx->hash, SHA512_H0, sizeof(ctx->hash));
+}
+
+/**
+ * Initialize context before calculaing hash.
+ *
+ * @param ctx context to initialize
+ */
+void rhash_sha384_init(struct sha512_ctx *ctx)
+{
+ /* Initial values from FIPS 180-3. These words were obtained by taking
+ * the first sixty-four bits of the fractional parts of the square
+ * roots of ninth through sixteenth prime numbers. */
+ static const uint64_t SHA384_H0[8] = {
+ I64(0xcbbb9d5dc1059ed8), I64(0x629a292a367cd507), I64(0x9159015a3070dd17),
+ I64(0x152fecd8f70e5939), I64(0x67332667ffc00b31), I64(0x8eb44a8768581511),
+ I64(0xdb0c2e0d64f98fa7), I64(0x47b5481dbefa4fa4)
+ };
+
+ ctx->length = 0;
+ ctx->digest_length = sha384_hash_size;
+
+ memcpy(ctx->hash, SHA384_H0, sizeof(ctx->hash));
+}
+
+/**
+ * The core transformation. Process a 512-bit block.
+ *
+ * @param hash algorithm state
+ * @param block the message block to process
+ */
+static void rhash_sha512_process_block(uint64_t hash[8], uint64_t block[16])
+{
+ uint64_t A, B, C, D, E, F, G, H;
+ uint64_t W[16];
+ const uint64_t *k;
+ int i;
+
+ A = hash[0], B = hash[1], C = hash[2], D = hash[3];
+ E = hash[4], F = hash[5], G = hash[6], H = hash[7];
+
+ /* Compute SHA using alternate Method: FIPS 180-3 6.1.3 */
+ ROUND_1_16(A, B, C, D, E, F, G, H, 0);
+ ROUND_1_16(H, A, B, C, D, E, F, G, 1);
+ ROUND_1_16(G, H, A, B, C, D, E, F, 2);
+ ROUND_1_16(F, G, H, A, B, C, D, E, 3);
+ ROUND_1_16(E, F, G, H, A, B, C, D, 4);
+ ROUND_1_16(D, E, F, G, H, A, B, C, 5);
+ ROUND_1_16(C, D, E, F, G, H, A, B, 6);
+ ROUND_1_16(B, C, D, E, F, G, H, A, 7);
+ ROUND_1_16(A, B, C, D, E, F, G, H, 8);
+ ROUND_1_16(H, A, B, C, D, E, F, G, 9);
+ ROUND_1_16(G, H, A, B, C, D, E, F, 10);
+ ROUND_1_16(F, G, H, A, B, C, D, E, 11);
+ ROUND_1_16(E, F, G, H, A, B, C, D, 12);
+ ROUND_1_16(D, E, F, G, H, A, B, C, 13);
+ ROUND_1_16(C, D, E, F, G, H, A, B, 14);
+ ROUND_1_16(B, C, D, E, F, G, H, A, 15);
+
+ for (i = 16, k = &rhash_k512[16]; i < 80; i += 16, k += 16) {
+ ROUND_17_80(A, B, C, D, E, F, G, H, 0);
+ ROUND_17_80(H, A, B, C, D, E, F, G, 1);
+ ROUND_17_80(G, H, A, B, C, D, E, F, 2);
+ ROUND_17_80(F, G, H, A, B, C, D, E, 3);
+ ROUND_17_80(E, F, G, H, A, B, C, D, 4);
+ ROUND_17_80(D, E, F, G, H, A, B, C, 5);
+ ROUND_17_80(C, D, E, F, G, H, A, B, 6);
+ ROUND_17_80(B, C, D, E, F, G, H, A, 7);
+ ROUND_17_80(A, B, C, D, E, F, G, H, 8);
+ ROUND_17_80(H, A, B, C, D, E, F, G, 9);
+ ROUND_17_80(G, H, A, B, C, D, E, F, 10);
+ ROUND_17_80(F, G, H, A, B, C, D, E, 11);
+ ROUND_17_80(E, F, G, H, A, B, C, D, 12);
+ ROUND_17_80(D, E, F, G, H, A, B, C, 13);
+ ROUND_17_80(C, D, E, F, G, H, A, B, 14);
+ ROUND_17_80(B, C, D, E, F, G, H, A, 15);
+ }
+
+ hash[0] += A, hash[1] += B, hash[2] += C, hash[3] += D;
+ hash[4] += E, hash[5] += F, hash[6] += G, hash[7] += H;
+}
+
+/**
+ * Calculate message hash.
+ * Can be called repeatedly with chunks of the message to be hashed.
+ *
+ * @param ctx the algorithm context containing current hashing state
+ * @param msg message chunk
+ * @param size length of the message chunk
+ */
+void rhash_sha512_update(sha512_ctx *ctx, const unsigned char *msg, size_t size)
+{
+ size_t index = (size_t)ctx->length & 127;
+ ctx->length += size;
+
+ /* fill partial block */
+ if (index) {
+ size_t left = sha512_block_size - index;
+ memcpy((char*)ctx->message + index, msg, (size < left ? size : left));
+ if (size < left) return;
+
+ /* process partial block */
+ rhash_sha512_process_block(ctx->hash, ctx->message);
+ msg += left;
+ size -= left;
+ }
+ while (size >= sha512_block_size) {
+ uint64_t* aligned_message_block;
+ if (IS_ALIGNED_64(msg)) {
+ /* the most common case is processing of an already aligned message
+ without copying it */
+ aligned_message_block = (uint64_t*)msg;
+ } else {
+ memcpy(ctx->message, msg, sha512_block_size);
+ aligned_message_block = ctx->message;
+ }
+
+ rhash_sha512_process_block(ctx->hash, aligned_message_block);
+ msg += sha512_block_size;
+ size -= sha512_block_size;
+ }
+ if (size) {
+ memcpy(ctx->message, msg, size); /* save leftovers */
+ }
+}
+
+/**
+ * Store calculated hash into the given array.
+ *
+ * @param ctx the algorithm context containing current hashing state
+ * @param result calculated hash in binary form
+ */
+void rhash_sha512_final(sha512_ctx *ctx, unsigned char* result)
+{
+ size_t index = ((unsigned)ctx->length & 127) >> 3;
+ unsigned shift = ((unsigned)ctx->length & 7) * 8;
+
+ /* pad message and process the last block */
+
+ /* append the byte 0x80 to the message */
+ ctx->message[index] &= le2me_64( ~(I64(0xFFFFFFFFFFFFFFFF) << shift) );
+ ctx->message[index++] ^= le2me_64( I64(0x80) << shift );
+
+ /* if no room left in the message to store 128-bit message length */
+ if (index >= 15) {
+ if (index == 15) ctx->message[index] = 0;
+ rhash_sha512_process_block(ctx->hash, ctx->message);
+ index = 0;
+ }
+ while (index < 15) {
+ ctx->message[index++] = 0;
+ }
+ ctx->message[15] = be2me_64(ctx->length << 3);
+ rhash_sha512_process_block(ctx->hash, ctx->message);
+
+ if (result) be64_copy(result, 0, ctx->hash, ctx->digest_length);
+}
diff --git a/Utilities/cmlibrhash/librhash/sha512.h b/Utilities/cmlibrhash/librhash/sha512.h
new file mode 100644
index 0000000..7c689be
--- /dev/null
+++ b/Utilities/cmlibrhash/librhash/sha512.h
@@ -0,0 +1,32 @@
+/* sha.h sha512 and sha384 hash functions */
+#ifndef SHA512_H
+#define SHA512_H
+#include "ustd.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define sha512_block_size 128
+#define sha512_hash_size 64
+#define sha384_hash_size 48
+
+/* algorithm context */
+typedef struct sha512_ctx
+{
+ uint64_t message[16]; /* 1024-bit buffer for leftovers */
+ uint64_t length; /* number of processed bytes */
+ uint64_t hash[8]; /* 512-bit algorithm internal hashing state */
+ unsigned digest_length; /* length of the algorithm digest in bytes */
+} sha512_ctx;
+
+void rhash_sha384_init(sha512_ctx *ctx);
+void rhash_sha512_init(sha512_ctx *ctx);
+void rhash_sha512_update(sha512_ctx *ctx, const unsigned char* data, size_t length);
+void rhash_sha512_final(sha512_ctx *ctx, unsigned char* result);
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif /* __cplusplus */
+
+#endif /* SHA512_H */
diff --git a/Utilities/cmlibrhash/librhash/ustd.h b/Utilities/cmlibrhash/librhash/ustd.h
new file mode 100644
index 0000000..019b931
--- /dev/null
+++ b/Utilities/cmlibrhash/librhash/ustd.h
@@ -0,0 +1,39 @@
+/* ustd.h common macros and includes */
+#ifndef LIBRHASH_USTD_H
+#define LIBRHASH_USTD_H
+
+/* Include KWSys Large File Support configuration. */
+#include <cmsys/Configure.h>
+
+#if defined(_MSC_VER)
+# pragma warning(push,1)
+#endif
+
+#include <cm_kwiml.h>
+
+#ifndef KWIML_INT_HAVE_INT64_T
+# define int64_t KWIML_INT_int64_t
+#endif
+#ifndef KWIML_INT_HAVE_INT32_T
+# define int32_t KWIML_INT_int32_t
+#endif
+#ifndef KWIML_INT_HAVE_INT16_T
+# define int16_t KWIML_INT_int16_t
+#endif
+#ifndef KWIML_INT_HAVE_INT8_T
+# define int8_t KWIML_INT_int8_t
+#endif
+#ifndef KWIML_INT_HAVE_UINT64_T
+# define uint64_t KWIML_INT_uint64_t
+#endif
+#ifndef KWIML_INT_HAVE_UINT32_T
+# define uint32_t KWIML_INT_uint32_t
+#endif
+#ifndef KWIML_INT_HAVE_UINT16_T
+# define uint16_t KWIML_INT_uint16_t
+#endif
+#ifndef KWIML_INT_HAVE_UINT8_T
+# define uint8_t KWIML_INT_uint8_t
+#endif
+
+#endif /* LIBRHASH_USTD_H */
diff --git a/Utilities/cmlibrhash/librhash/util.h b/Utilities/cmlibrhash/librhash/util.h
new file mode 100644
index 0000000..9f37157
--- /dev/null
+++ b/Utilities/cmlibrhash/librhash/util.h
@@ -0,0 +1,31 @@
+/* util.h */
+#ifndef UTIL_H
+#define UTIL_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if (defined(__GNUC__) && __GNUC__ >= 4 && (__GNUC__ > 4 || __GNUC_MINOR__ >= 1) \
+ && defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4)) \
+ || (defined(__INTEL_COMPILER) && !defined(_WIN32))
+/* atomic operations are defined by ICC and GCC >= 4.1, but by the later one supposedly not for ARM */
+/* note: ICC on ia64 platform possibly require ia64intrin.h, need testing */
+# define atomic_compare_and_swap(ptr, oldval, newval) __sync_val_compare_and_swap(ptr, oldval, newval)
+#elif defined(_MSC_VER)
+# include <windows.h>
+# define atomic_compare_and_swap(ptr, oldval, newval) InterlockedCompareExchange(ptr, newval, oldval)
+#elif defined(__sun)
+# include <atomic.h>
+# define atomic_compare_and_swap(ptr, oldval, newval) atomic_cas_32(ptr, oldval, newval)
+#else
+/* pray that it will work */
+# define atomic_compare_and_swap(ptr, oldval, newval) { if(*(ptr) == (oldval)) *(ptr) = (newval); }
+# define NO_ATOMIC_BUILTINS
+#endif
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif /* __cplusplus */
+
+#endif /* UTIL_H */
diff --git a/bootstrap b/bootstrap
index 4ce0dee..d54380a 100755
--- a/bootstrap
+++ b/bootstrap
@@ -493,6 +493,8 @@ Configuration:
--no-system-liblzma use cmake-provided liblzma library (default)
--system-libarchive use system-installed libarchive library
--no-system-libarchive use cmake-provided libarchive library (default)
+ --system-librhash use system-installed librhash library
+ --no-system-librhash use cmake-provided librhash library (default)
--qt-gui build the Qt-based GUI (requires Qt >= 4.2)
--no-qt-gui do not build the Qt-based GUI (default)
@@ -726,10 +728,10 @@ while test $# != 0; do
--init=*) cmake_init_file=`cmake_arg "$1"` ;;
--system-libs) cmake_bootstrap_system_libs="${cmake_bootstrap_system_libs} -DCMAKE_USE_SYSTEM_LIBRARIES=1" ;;
--no-system-libs) cmake_bootstrap_system_libs="${cmake_bootstrap_system_libs} -DCMAKE_USE_SYSTEM_LIBRARIES=0" ;;
- --system-bzip2|--system-curl|--system-expat|--system-jsoncpp|--system-libarchive|--system-zlib|--system-liblzma)
+ --system-bzip2|--system-curl|--system-expat|--system-jsoncpp|--system-libarchive|--system-librhash|--system-zlib|--system-liblzma)
lib=`cmake_arg "$1" "--system-"`
cmake_bootstrap_system_libs="${cmake_bootstrap_system_libs} -DCMAKE_USE_SYSTEM_LIBRARY_`cmake_toupper $lib`=1" ;;
- --no-system-bzip2|--no-system-curl|--no-system-expat|--no-system-jsoncpp|--no-system-libarchive|--no-system-zlib|--no-system-liblzma)
+ --no-system-bzip2|--no-system-curl|--no-system-expat|--no-system-jsoncpp|--no-system-libarchive|--no-system-librhash|--no-system-zlib|--no-system-liblzma)
lib=`cmake_arg "$1" "--no-system-"`
cmake_bootstrap_system_libs="${cmake_bootstrap_system_libs} -DCMAKE_USE_SYSTEM_LIBRARY_`cmake_toupper $lib`=0" ;;
--qt-gui) cmake_bootstrap_qt_gui="1" ;;