mirror of
https://github.com/ukui/apt.git
synced 2026-03-09 09:35:45 -07:00
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:
@@ -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)
|
||||
@@ -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)
|
||||
|
||||
@@ -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
@@ -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)) { }
|
||||
|
||||
@@ -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;
|
||||
|
||||
Vendored
+1
@@ -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],
|
||||
|
||||
Reference in New Issue
Block a user