QCryptographicHash: move EVP struct into the contexts union
... making it just another context. Well, except the EVP struct has non-trivial SMFs, so adding it to the union deletes all the union's SMFs, too. To restore them, we need to give the union a class name (State). Since we anyway need to provide ctors, inline all init() functions into them. State having a ctor means we need to call it, with the method argument, in the Private ctor-init-list. That requires the State member to have a name. Since the union thus no longer defines variant members within Private, move most of the functions that operated on the variant members into State or EVP to avoid having to sprinkle state./evp.-prefixes all over the code. This gives the opportunity to re-share some code that was duplicated when we dragged #ifdef USING_OPENSSL3 out of the functions into namespace scope. The move of the functions into State robs them of their access to other Private members, to wit, 'method' and 'result', so we have to pass them as arguments now. I tried to split this up into smaller patches, but it kinda has to happen all at once, sorry. Pick-to: 6.5 Change-Id: If864d4d46075d00420f6e849cd68c4b824c1a50a Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>bb10
parent
b1919f01c8
commit
e80fc16cec
|
|
@ -296,13 +296,14 @@ class QCryptographicHashPrivate
|
|||
{
|
||||
public:
|
||||
explicit QCryptographicHashPrivate(QCryptographicHash::Algorithm method) noexcept
|
||||
: method(method)
|
||||
: state(method), method(method)
|
||||
{
|
||||
init();
|
||||
reset();
|
||||
}
|
||||
~QCryptographicHashPrivate()
|
||||
{
|
||||
state.destroy(method);
|
||||
}
|
||||
|
||||
void init();
|
||||
void reset() noexcept;
|
||||
void addData(QByteArrayView bytes) noexcept;
|
||||
bool addData(QIODevice *dev);
|
||||
|
|
@ -330,18 +331,30 @@ public:
|
|||
struct EVP {
|
||||
EVP_MD_ptr algorithm;
|
||||
EVP_MD_CTX_ptr context;
|
||||
bool initializationFailed = false;
|
||||
bool initializationFailed;
|
||||
|
||||
void init(QCryptographicHash::Algorithm method);
|
||||
explicit EVP(QCryptographicHash::Algorithm method);
|
||||
void reset() noexcept;
|
||||
void finalizeUnchecked(HashResult &result) noexcept;
|
||||
} evp;
|
||||
};
|
||||
#endif
|
||||
|
||||
union {
|
||||
union State {
|
||||
explicit State(QCryptographicHash::Algorithm method);
|
||||
void destroy(QCryptographicHash::Algorithm method);
|
||||
#ifdef USING_OPENSSL30
|
||||
~State() {}
|
||||
#endif
|
||||
|
||||
void reset(QCryptographicHash::Algorithm method) noexcept;
|
||||
void addData(QCryptographicHash::Algorithm method, QByteArrayView data) noexcept;
|
||||
void finalizeUnchecked(QCryptographicHash::Algorithm method, HashResult &result) noexcept;
|
||||
|
||||
Sha1State sha1Context;
|
||||
#ifndef QT_CRYPTOGRAPHICHASH_ONLY_SHA1
|
||||
#ifndef USING_OPENSSL30
|
||||
#ifdef USING_OPENSSL30
|
||||
EVP evp;
|
||||
#else
|
||||
MD5Context md5Context;
|
||||
md4_context md4Context;
|
||||
SHA224Context sha224Context;
|
||||
|
|
@ -349,21 +362,14 @@ public:
|
|||
SHA384Context sha384Context;
|
||||
SHA512Context sha512Context;
|
||||
SHA3Context sha3Context;
|
||||
|
||||
enum class Sha3Variant { Sha3, Keccak };
|
||||
void sha3Finish(HashResult &result, int bitCount, Sha3Variant sha3Variant);
|
||||
#endif
|
||||
blake2b_state blake2bContext;
|
||||
blake2s_state blake2sContext;
|
||||
#endif
|
||||
};
|
||||
#ifndef QT_CRYPTOGRAPHICHASH_ONLY_SHA1
|
||||
#ifndef USING_OPENSSL30
|
||||
enum class Sha3Variant
|
||||
{
|
||||
Sha3,
|
||||
Keccak
|
||||
};
|
||||
void sha3Finish(int bitCount, Sha3Variant sha3Variant);
|
||||
#endif
|
||||
#endif
|
||||
} state;
|
||||
// protects result in finalize()
|
||||
QBasicMutex finalizeMutex;
|
||||
HashResult result;
|
||||
|
|
@ -373,7 +379,8 @@ public:
|
|||
|
||||
#ifndef QT_CRYPTOGRAPHICHASH_ONLY_SHA1
|
||||
#ifndef USING_OPENSSL30
|
||||
void QCryptographicHashPrivate::sha3Finish(int bitCount, Sha3Variant sha3Variant)
|
||||
void QCryptographicHashPrivate::State::sha3Finish(HashResult &result, int bitCount,
|
||||
Sha3Variant sha3Variant)
|
||||
{
|
||||
/*
|
||||
FIPS 202 §6.1 defines SHA-3 in terms of calculating the Keccak function
|
||||
|
|
@ -539,27 +546,38 @@ QCryptographicHash::Algorithm QCryptographicHash::algorithm() const noexcept
|
|||
|
||||
#ifdef USING_OPENSSL30
|
||||
|
||||
void QCryptographicHashPrivate::init()
|
||||
QCryptographicHashPrivate::State::State(QCryptographicHash::Algorithm method)
|
||||
{
|
||||
if (method == QCryptographicHash::Blake2b_160 ||
|
||||
method == QCryptographicHash::Blake2b_256 ||
|
||||
method == QCryptographicHash::Blake2b_384) {
|
||||
new (&blake2bContext) blake2b_state;
|
||||
reset(method);
|
||||
} else if (method == QCryptographicHash::Blake2s_128 ||
|
||||
method == QCryptographicHash::Blake2s_160 ||
|
||||
method == QCryptographicHash::Blake2s_224) {
|
||||
new (&blake2sContext) blake2s_state;
|
||||
reset(method);
|
||||
} else {
|
||||
evp.init(method);
|
||||
new (&evp) EVP(method);
|
||||
}
|
||||
}
|
||||
|
||||
void QCryptographicHashPrivate::EVP::init(QCryptographicHash::Algorithm method)
|
||||
void QCryptographicHashPrivate::State::destroy(QCryptographicHash::Algorithm method)
|
||||
{
|
||||
Q_ASSERT(!context);
|
||||
|
||||
initializationFailed = true;
|
||||
if (method != QCryptographicHash::Blake2b_160 &&
|
||||
method != QCryptographicHash::Blake2b_256 &&
|
||||
method != QCryptographicHash::Blake2b_384 &&
|
||||
method != QCryptographicHash::Blake2s_128 &&
|
||||
method != QCryptographicHash::Blake2s_160 &&
|
||||
method != QCryptographicHash::Blake2s_224) {
|
||||
evp.~EVP();
|
||||
}
|
||||
}
|
||||
|
||||
QCryptographicHashPrivate::EVP::EVP(QCryptographicHash::Algorithm method)
|
||||
: initializationFailed{true}
|
||||
{
|
||||
if (method == QCryptographicHash::Md4) {
|
||||
/*
|
||||
* We need to load the legacy provider in order to have the MD4
|
||||
|
|
@ -592,7 +610,7 @@ void QCryptographicHashPrivate::EVP::init(QCryptographicHash::Algorithm method)
|
|||
|
||||
#else // USING_OPENSSL30
|
||||
|
||||
void QCryptographicHashPrivate::init()
|
||||
QCryptographicHashPrivate::State::State(QCryptographicHash::Algorithm method)
|
||||
{
|
||||
switch (method) {
|
||||
case QCryptographicHash::Sha1:
|
||||
|
|
@ -648,15 +666,25 @@ void QCryptographicHashPrivate::init()
|
|||
case QCryptographicHash::NumAlgorithms:
|
||||
Q_UNREACHABLE();
|
||||
}
|
||||
reset(method);
|
||||
}
|
||||
|
||||
void QCryptographicHashPrivate::State::destroy(QCryptographicHash::Algorithm)
|
||||
{
|
||||
static_assert(std::is_trivially_destructible_v<State>); // so nothing to do here
|
||||
}
|
||||
#endif // !USING_OPENSSL30
|
||||
|
||||
#ifdef USING_OPENSSL30
|
||||
|
||||
void QCryptographicHashPrivate::reset() noexcept
|
||||
{
|
||||
result.clear();
|
||||
state.reset(method);
|
||||
}
|
||||
|
||||
#ifdef USING_OPENSSL30
|
||||
|
||||
void QCryptographicHashPrivate::State::reset(QCryptographicHash::Algorithm method) noexcept
|
||||
{
|
||||
if (method == QCryptographicHash::Blake2b_160 ||
|
||||
method == QCryptographicHash::Blake2b_256 ||
|
||||
method == QCryptographicHash::Blake2b_384) {
|
||||
|
|
@ -684,9 +712,8 @@ void QCryptographicHashPrivate::EVP::reset() noexcept
|
|||
|
||||
#else // USING_OPENSSL30
|
||||
|
||||
void QCryptographicHashPrivate::reset() noexcept
|
||||
void QCryptographicHashPrivate::State::reset(QCryptographicHash::Algorithm method) noexcept
|
||||
{
|
||||
result.clear();
|
||||
switch (method) {
|
||||
case QCryptographicHash::Sha1:
|
||||
sha1InitState(&sha1Context);
|
||||
|
|
@ -771,9 +798,16 @@ void QCryptographicHash::addData(QByteArrayView bytes) noexcept
|
|||
d->addData(bytes);
|
||||
}
|
||||
|
||||
void QCryptographicHashPrivate::addData(QByteArrayView bytes) noexcept
|
||||
{
|
||||
state.addData(method, bytes);
|
||||
result.clear();
|
||||
}
|
||||
|
||||
#ifdef USING_OPENSSL30
|
||||
|
||||
void QCryptographicHashPrivate::addData(QByteArrayView bytes) noexcept
|
||||
void QCryptographicHashPrivate::State::addData(QCryptographicHash::Algorithm method,
|
||||
QByteArrayView bytes) noexcept
|
||||
{
|
||||
const char *data = bytes.data();
|
||||
auto length = bytes.size();
|
||||
|
|
@ -791,12 +825,12 @@ void QCryptographicHashPrivate::addData(QByteArrayView bytes) noexcept
|
|||
EVP_DigestUpdate(evp.context.get(), (const unsigned char *)data, length);
|
||||
}
|
||||
}
|
||||
result.clear();
|
||||
}
|
||||
|
||||
#else // USING_OPENSSL30
|
||||
|
||||
void QCryptographicHashPrivate::addData(QByteArrayView bytes) noexcept
|
||||
void QCryptographicHashPrivate::State::addData(QCryptographicHash::Algorithm method,
|
||||
QByteArrayView bytes) noexcept
|
||||
{
|
||||
const char *data = bytes.data();
|
||||
auto length = bytes.size();
|
||||
|
|
@ -865,7 +899,6 @@ void QCryptographicHashPrivate::addData(QByteArrayView bytes) noexcept
|
|||
Q_UNREACHABLE();
|
||||
}
|
||||
}
|
||||
result.clear();
|
||||
}
|
||||
#endif // !USING_OPENSSL30
|
||||
|
||||
|
|
@ -945,8 +978,14 @@ void QCryptographicHashPrivate::finalize() noexcept
|
|||
Must be called with finalizeMutex held (except from static hash() function,
|
||||
where no sharing can take place).
|
||||
*/
|
||||
#ifdef USING_OPENSSL30
|
||||
void QCryptographicHashPrivate::finalizeUnchecked() noexcept
|
||||
{
|
||||
state.finalizeUnchecked(method, result);
|
||||
}
|
||||
|
||||
#ifdef USING_OPENSSL30
|
||||
void QCryptographicHashPrivate::State::finalizeUnchecked(QCryptographicHash::Algorithm method,
|
||||
HashResult &result) noexcept
|
||||
{
|
||||
if (method == QCryptographicHash::Blake2b_160 ||
|
||||
method == QCryptographicHash::Blake2b_256 ||
|
||||
|
|
@ -979,7 +1018,8 @@ void QCryptographicHashPrivate::EVP::finalizeUnchecked(HashResult &result) noexc
|
|||
|
||||
#else // USING_OPENSSL30
|
||||
|
||||
void QCryptographicHashPrivate::finalizeUnchecked() noexcept
|
||||
void QCryptographicHashPrivate::State::finalizeUnchecked(QCryptographicHash::Algorithm method,
|
||||
HashResult &result) noexcept
|
||||
{
|
||||
switch (method) {
|
||||
case QCryptographicHash::Sha1: {
|
||||
|
|
@ -1035,14 +1075,14 @@ void QCryptographicHashPrivate::finalizeUnchecked() noexcept
|
|||
case QCryptographicHash::RealSha3_256:
|
||||
case QCryptographicHash::RealSha3_384:
|
||||
case QCryptographicHash::RealSha3_512: {
|
||||
sha3Finish(8 * hashLengthInternal(method), Sha3Variant::Sha3);
|
||||
sha3Finish(result, 8 * hashLengthInternal(method), Sha3Variant::Sha3);
|
||||
break;
|
||||
}
|
||||
case QCryptographicHash::Keccak_224:
|
||||
case QCryptographicHash::Keccak_256:
|
||||
case QCryptographicHash::Keccak_384:
|
||||
case QCryptographicHash::Keccak_512: {
|
||||
sha3Finish(8 * hashLengthInternal(method), Sha3Variant::Keccak);
|
||||
sha3Finish(result, 8 * hashLengthInternal(method), Sha3Variant::Keccak);
|
||||
break;
|
||||
}
|
||||
case QCryptographicHash::Blake2b_160:
|
||||
|
|
|
|||
Loading…
Reference in New Issue