QCryptographicHash: centralize resizeForOverwrite() call

hashLengthInternal() already returns the size for each algorithm, so call
resizeForOverwrite() in one place. The hash lengths are specified by the
respective RFCs, so they have to be the same with/without OpenSSL
(confirmed by looking at the OpenSSL source code). So use
hashLengthInternal() in the EVP code paths and replace
result.resizeForOverwrite(EVP_MD_get_size()) call with an assert.

MD4_RESULTLEN isn't available when USING_OPENSSL30 is defined,
hashLengthInternal() returns 16 for md4, since MD4_RESULTLEN == 16,
just use 16 directly.

Change-Id: I5526d5e840b4882f3e5229df239b86924daee475
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Reviewed-by: Marc Mutz <marc.mutz@qt.io>
(cherry picked from commit 8786a930d1fee3ad330166a056c87684802733b6)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
This commit is contained in:
Ahmad Samir 2025-03-03 20:02:06 +02:00 committed by Qt Cherry-pick Bot
parent db36fea295
commit f92b172757

View File

@ -322,7 +322,7 @@ public:
SHA3Context sha3Context;
enum class Sha3Variant { Sha3, Keccak };
static void sha3Finish(SHA3Context &ctx, HashResult &result, int bitCount, Sha3Variant sha3Variant);
static void sha3Finish(SHA3Context &ctx, HashResult &result, Sha3Variant sha3Variant);
blake2b_state blake2bContext;
blake2s_state blake2sContext;
#endif
@ -336,7 +336,7 @@ public:
#ifndef QT_CRYPTOGRAPHICHASH_ONLY_SHA1
void QCryptographicHashPrivate::State::sha3Finish(SHA3Context &ctx, HashResult &result,
int bitCount, Sha3Variant sha3Variant)
Sha3Variant sha3Variant)
{
/*
FIPS 202 §6.1 defines SHA-3 in terms of calculating the Keccak function
@ -360,8 +360,6 @@ void QCryptographicHashPrivate::State::sha3Finish(SHA3Context &ctx, HashResult &
*/
static const unsigned char sha3FinalSuffix = 0x80;
result.resizeForOverwrite(bitCount / 8);
switch (sha3Variant) {
case Sha3Variant::Sha3:
sha3Update(&ctx, reinterpret_cast<const BitSequence *>(&sha3FinalSuffix), 2);
@ -954,6 +952,7 @@ void QCryptographicHashPrivate::finalize() noexcept
*/
void QCryptographicHashPrivate::finalizeUnchecked() noexcept
{
result.resizeForOverwrite(hashLengthInternal(method));
state.finalizeUnchecked(method, result);
}
@ -966,20 +965,18 @@ void QCryptographicHashPrivate::State::finalizeUnchecked(QCryptographicHash::Alg
method == QCryptographicHash::Keccak_384 ||
method == QCryptographicHash::Keccak_512) {
SHA3Context copy = sha3Context;
sha3Finish(copy, result, 8 * hashLengthInternal(method), Sha3Variant::Keccak);
sha3Finish(copy, result, Sha3Variant::Keccak);
} else if (method == QCryptographicHash::Blake2b_160 ||
method == QCryptographicHash::Blake2b_256 ||
method == QCryptographicHash::Blake2b_384) {
const auto length = hashLengthInternal(method);
blake2b_state copy = blake2bContext;
result.resizeForOverwrite(length);
blake2b_final(&copy, result.data(), length);
} else if (method == QCryptographicHash::Blake2s_128 ||
method == QCryptographicHash::Blake2s_160 ||
method == QCryptographicHash::Blake2s_224) {
const auto length = hashLengthInternal(method);
blake2s_state copy = blake2sContext;
result.resizeForOverwrite(length);
blake2s_final(&copy, result.data(), length);
} else {
evp.finalizeUnchecked(result);
@ -991,7 +988,7 @@ void QCryptographicHashPrivate::EVP::finalizeUnchecked(HashResult &result) noexc
if (!initializationFailed) {
EVP_MD_CTX_ptr copy = EVP_MD_CTX_ptr(EVP_MD_CTX_new());
EVP_MD_CTX_copy_ex(copy.get(), context.get());
result.resizeForOverwrite(EVP_MD_get_size(algorithm.get()));
Q_ASSERT(result.size() == EVP_MD_get_size(algorithm.get()));
EVP_DigestFinal_ex(copy.get(), result.data(), nullptr);
}
}
@ -1004,7 +1001,6 @@ void QCryptographicHashPrivate::State::finalizeUnchecked(QCryptographicHash::Alg
switch (method) {
case QCryptographicHash::Sha1: {
Sha1State copy = sha1Context;
result.resizeForOverwrite(20);
sha1FinalizeState(&copy);
sha1ToHash(&copy, result.data());
break;
@ -1017,37 +1013,31 @@ void QCryptographicHashPrivate::State::finalizeUnchecked(QCryptographicHash::Alg
#else
case QCryptographicHash::Md4: {
md4_context copy = md4Context;
result.resizeForOverwrite(MD4_RESULTLEN);
md4_final(&copy, result.data());
break;
}
case QCryptographicHash::Md5: {
MD5Context copy = md5Context;
result.resizeForOverwrite(16);
MD5Final(&copy, result.data());
break;
}
case QCryptographicHash::Sha224: {
SHA224Context copy = sha224Context;
result.resizeForOverwrite(SHA224HashSize);
SHA224Result(&copy, result.data());
break;
}
case QCryptographicHash::Sha256: {
SHA256Context copy = sha256Context;
result.resizeForOverwrite(SHA256HashSize);
SHA256Result(&copy, result.data());
break;
}
case QCryptographicHash::Sha384: {
SHA384Context copy = sha384Context;
result.resizeForOverwrite(SHA384HashSize);
SHA384Result(&copy, result.data());
break;
}
case QCryptographicHash::Sha512: {
SHA512Context copy = sha512Context;
result.resizeForOverwrite(SHA512HashSize);
SHA512Result(&copy, result.data());
break;
}
@ -1056,7 +1046,7 @@ void QCryptographicHashPrivate::State::finalizeUnchecked(QCryptographicHash::Alg
case QCryptographicHash::RealSha3_384:
case QCryptographicHash::RealSha3_512: {
SHA3Context copy = sha3Context;
sha3Finish(copy, result, 8 * hashLengthInternal(method), Sha3Variant::Sha3);
sha3Finish(copy, result, Sha3Variant::Sha3);
break;
}
case QCryptographicHash::Keccak_224:
@ -1064,7 +1054,7 @@ void QCryptographicHashPrivate::State::finalizeUnchecked(QCryptographicHash::Alg
case QCryptographicHash::Keccak_384:
case QCryptographicHash::Keccak_512: {
SHA3Context copy = sha3Context;
sha3Finish(copy, result, 8 * hashLengthInternal(method), Sha3Variant::Keccak);
sha3Finish(copy, result, Sha3Variant::Keccak);
break;
}
case QCryptographicHash::Blake2b_160:
@ -1073,7 +1063,6 @@ void QCryptographicHashPrivate::State::finalizeUnchecked(QCryptographicHash::Alg
case QCryptographicHash::Blake2b_512: {
const auto length = hashLengthInternal(method);
blake2b_state copy = blake2bContext;
result.resizeForOverwrite(length);
blake2b_final(&copy, result.data(), length);
break;
}
@ -1083,7 +1072,6 @@ void QCryptographicHashPrivate::State::finalizeUnchecked(QCryptographicHash::Alg
case QCryptographicHash::Blake2s_256: {
const auto length = hashLengthInternal(method);
blake2s_state copy = blake2sContext;
result.resizeForOverwrite(length);
blake2s_final(&copy, result.data(), length);
break;
}