hashes: Use Libgcrypt for hashing purposes

Switch the code of the Hashes class to use libgcrypt, which allows
us to use hardware-accelerated implementations of SHA1 and friends.
This commit is contained in:
Julian Andres Klode
2020-01-07 19:21:40 +01:00
parent cfeae24843
commit 814ffcfaf3
6 changed files with 104 additions and 40 deletions
+25
View File
@@ -0,0 +1,25 @@
# - Try to find GCRYPT
# Once done, this will define
#
# GCRYPT_FOUND - system has GCRYPT
# GCRYPT_INCLUDE_DIRS - the GCRYPT include directories
# GCRYPT_LIBRARIES - the GCRYPT library
find_package(PkgConfig)
pkg_check_modules(GCRYPT_PKGCONF libgcrypt)
find_path(GCRYPT_INCLUDE_DIRS
NAMES gcrypt.h
PATHS ${GCRYPT_PKGCONF_INCLUDE_DIRS}
)
find_library(GCRYPT_LIBRARIES
NAMES gcrypt
PATHS ${GCRYPT_PKGCONF_LIBRARY_DIRS}
)
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(GCRYPT DEFAULT_MSG GCRYPT_INCLUDE_DIRS GCRYPT_LIBRARIES)
mark_as_advanced(GCRYPT_INCLUDE_DIRS GCRYPT_LIBRARIES)
+2
View File
@@ -134,6 +134,8 @@ if (SECCOMP_FOUND)
set(HAVE_SECCOMP 1)
endif()
find_package(Gcrypt REQUIRED)
# Mount()ing and stat()ing and friends
check_symbol_exists(statfs sys/vfs.h HAVE_VFS_H)
check_include_files(sys/params.h HAVE_PARAMS_H)
+2
View File
@@ -48,6 +48,7 @@ target_include_directories(apt-pkg
$<$<BOOL:${UDEV_FOUND}>:${UDEV_INCLUDE_DIRS}>
$<$<BOOL:${SYSTEMD_FOUND}>:${SYSTEMD_INCLUDE_DIRS}>
${ICONV_INCLUDE_DIRS}
$<$<BOOL:${GCRYPT_FOUND}>:${GCRYPT_INCLUDE_DIRS}>
)
target_link_libraries(apt-pkg
@@ -61,6 +62,7 @@ target_link_libraries(apt-pkg
$<$<BOOL:${UDEV_FOUND}>:${UDEV_LIBRARIES}>
$<$<BOOL:${SYSTEMD_FOUND}>:${SYSTEMD_LIBRARIES}>
${ICONV_LIBRARIES}
$<$<BOOL:${GCRYPT_FOUND}>:${GCRYPT_LIBRARIES}>
)
set_target_properties(apt-pkg PROPERTIES VERSION ${MAJOR}.${MINOR})
set_target_properties(apt-pkg PROPERTIES SOVERSION ${MAJOR})
+70 -36
View File
@@ -15,18 +15,30 @@
#include <apt-pkg/configuration.h>
#include <apt-pkg/fileutl.h>
#include <apt-pkg/hashes.h>
#include <apt-pkg/md5.h>
#include <apt-pkg/sha1.h>
#include <apt-pkg/sha2.h>
#include <algorithm>
#include <iostream>
#include <string>
#include <assert.h>
#include <stddef.h>
#include <stdlib.h>
#include <unistd.h>
#include <gcrypt.h>
/*}}}*/
static const constexpr struct HashAlgo
{
const char *name;
int gcryAlgo;
Hashes::SupportedHashes ourAlgo;
} Algorithms[] = {
{"MD5Sum", GCRY_MD_MD5, Hashes::MD5SUM},
{"SHA1", GCRY_MD_SHA1, Hashes::SHA1SUM},
{"SHA256", GCRY_MD_SHA256, Hashes::SHA256SUM},
{"SHA512", GCRY_MD_SHA512, Hashes::SHA512SUM},
};
const char * HashString::_SupportedHashes[] =
{
"SHA512", "SHA256", "SHA1", "MD5Sum", "Checksum-FileSize", NULL
@@ -286,39 +298,41 @@ bool HashStringList::operator!=(HashStringList const &other) const
class PrivateHashes {
public:
unsigned long long FileSize;
unsigned int CalcHashes;
gcry_md_hd_t hd;
explicit PrivateHashes(unsigned int const CalcHashes) : FileSize(0)
{
gcry_md_open(&hd, 0, 0);
for (auto & Algo : Algorithms)
{
if ((CalcHashes & Algo.ourAlgo) == Algo.ourAlgo)
gcry_md_enable(hd, Algo.gcryAlgo);
}
}
explicit PrivateHashes(unsigned int const CalcHashes) : FileSize(0), CalcHashes(CalcHashes) {}
explicit PrivateHashes(HashStringList const &Hashes) : FileSize(0) {
unsigned int calcHashes = Hashes.usable() ? 0 : ~0;
if (Hashes.find("MD5Sum") != NULL)
calcHashes |= Hashes::MD5SUM;
if (Hashes.find("SHA1") != NULL)
calcHashes |= Hashes::SHA1SUM;
if (Hashes.find("SHA256") != NULL)
calcHashes |= Hashes::SHA256SUM;
if (Hashes.find("SHA512") != NULL)
calcHashes |= Hashes::SHA512SUM;
CalcHashes = calcHashes;
gcry_md_open(&hd, 0, 0);
for (auto & Algo : Algorithms)
{
if (not Hashes.usable() || Hashes.find(Algo.name) != NULL)
gcry_md_enable(hd, Algo.gcryAlgo);
}
}
~PrivateHashes()
{
gcry_md_close(hd);
}
};
/*}}}*/
// Hashes::Add* - Add the contents of data or FD /*{{{*/
bool Hashes::Add(const unsigned char * const Data, unsigned long long const Size)
{
if (Size == 0)
return true;
bool Res = true;
if ((d->CalcHashes & MD5SUM) == MD5SUM)
Res &= MD5.Add(Data, Size);
if ((d->CalcHashes & SHA1SUM) == SHA1SUM)
Res &= SHA1.Add(Data, Size);
if ((d->CalcHashes & SHA256SUM) == SHA256SUM)
Res &= SHA256.Add(Data, Size);
if ((d->CalcHashes & SHA512SUM) == SHA512SUM)
Res &= SHA512.Add(Data, Size);
d->FileSize += Size;
return Res;
if (Size != 0)
{
gcry_md_write(d->hd, Data, Size);
d->FileSize += Size;
}
return true;
}
bool Hashes::AddFD(int const Fd,unsigned long long Size)
{
@@ -364,18 +378,38 @@ bool Hashes::AddFD(FileFd &Fd,unsigned long long Size)
return true;
}
/*}}}*/
static APT_PURE std::string HexDigest(gcry_md_hd_t hd, int algo)
{
char Conv[16] =
{'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b',
'c', 'd', 'e', 'f'};
auto Size = gcry_md_get_algo_dlen(algo);
char Result[((Size)*2) + 1];
Result[(Size)*2] = 0;
auto Sum = gcry_md_read(hd, algo);
// Convert each char into two letters
size_t J = 0;
size_t I = 0;
for (; I != (Size)*2; J++, I += 2)
{
Result[I] = Conv[Sum[J] >> 4];
Result[I + 1] = Conv[Sum[J] & 0xF];
}
return std::string(Result);
};
HashStringList Hashes::GetHashStringList()
{
HashStringList hashes;
if ((d->CalcHashes & MD5SUM) == MD5SUM)
hashes.push_back(HashString("MD5Sum", MD5.Result().Value()));
if ((d->CalcHashes & SHA1SUM) == SHA1SUM)
hashes.push_back(HashString("SHA1", SHA1.Result().Value()));
if ((d->CalcHashes & SHA256SUM) == SHA256SUM)
hashes.push_back(HashString("SHA256", SHA256.Result().Value()));
if ((d->CalcHashes & SHA512SUM) == SHA512SUM)
hashes.push_back(HashString("SHA512", SHA512.Result().Value()));
for (auto & Algo : Algorithms)
if (gcry_md_is_enabled(d->hd, Algo.gcryAlgo))
hashes.push_back(HashString(Algo.name, HexDigest(d->hd, Algo.gcryAlgo)));
hashes.FileSize(d->FileSize);
return hashes;
}
Hashes::Hashes() : d(new PrivateHashes(~0)) { }
+4 -4
View File
@@ -173,10 +173,10 @@ class Hashes
PrivateHashes * const d;
/* TODO: those will disappear in the future as it is hard to add new ones this way.
* Use Add* to build the results and get them via GetHashStringList() instead */
MD5Summation MD5;
SHA1Summation SHA1;
SHA256Summation SHA256;
SHA512Summation SHA512;
MD5Summation MD5 APT_PKG_590("Remove");
SHA1Summation SHA1 APT_PKG_590("Remove");
SHA256Summation SHA256 APT_PKG_590("Remove");
SHA512Summation SHA512 APT_PKG_590("Remove");
public:
static const int UntilEOF = 0;
+1
View File
@@ -17,6 +17,7 @@ Build-Depends: cmake (>= 3.4),
libbz2-dev,
libdb-dev,
libgnutls28-dev (>= 3.4.6),
libgcrypt20-dev,
liblz4-dev (>= 0.0~r126),
liblzma-dev,
libseccomp-dev [amd64 arm64 armel armhf i386 mips mips64el mipsel ppc64el s390x hppa powerpc powerpcspe ppc64 x32],