summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/corelib/tools/qcryptographichash.cpp91
-rw-r--r--src/corelib/tools/qcryptographichash.h3
-rw-r--r--src/corelib/tools/qmessageauthenticationcode.cpp2
-rw-r--r--src/network/kernel/qauthenticator.cpp3
-rw-r--r--src/plugins/tls/shared/qtlskey_generic.cpp4
-rw-r--r--tests/auto/corelib/tools/qcryptographichash/tst_qcryptographichash.cpp12
6 files changed, 78 insertions, 37 deletions
diff --git a/src/corelib/tools/qcryptographichash.cpp b/src/corelib/tools/qcryptographichash.cpp
index 512d38b02b..f44dee89d4 100644
--- a/src/corelib/tools/qcryptographichash.cpp
+++ b/src/corelib/tools/qcryptographichash.cpp
@@ -138,47 +138,53 @@ static inline int SHA384_512AddLength(SHA512Context *context, unsigned int lengt
QT_BEGIN_NAMESPACE
+static constexpr qsizetype MaxHashLength = 64;
+
static constexpr int hashLengthInternal(QCryptographicHash::Algorithm method) noexcept
{
switch (method) {
- case QCryptographicHash::Sha1:
- return 20;
+#define CASE(Enum, Size) \
+ case QCryptographicHash:: Enum : \
+ /* if this triggers, then increase MaxHashLength accordingly */ \
+ static_assert(MaxHashLength >= qsizetype(Size) ); \
+ return Size \
+ /*end*/
+ CASE(Sha1, 20);
#ifndef QT_CRYPTOGRAPHICHASH_ONLY_SHA1
- case QCryptographicHash::Md4:
- return 16;
- case QCryptographicHash::Md5:
- return 16;
- case QCryptographicHash::Sha224:
- return SHA224HashSize;
- case QCryptographicHash::Sha256:
- return SHA256HashSize;
- case QCryptographicHash::Sha384:
- return SHA384HashSize;
- case QCryptographicHash::Sha512:
- return SHA512HashSize;
- case QCryptographicHash::Blake2s_128:
- return 128 / 8;
+ CASE(Md4, 16);
+ CASE(Md5, 16);
+ CASE(Sha224, SHA224HashSize);
+ CASE(Sha256, SHA256HashSize);
+ CASE(Sha384, SHA384HashSize);
+ CASE(Sha512, SHA512HashSize);
+ CASE(Blake2s_128, 128 / 8);
case QCryptographicHash::Blake2b_160:
case QCryptographicHash::Blake2s_160:
+ static_assert(160 / 8 <= MaxHashLength);
return 160 / 8;
case QCryptographicHash::RealSha3_224:
case QCryptographicHash::Keccak_224:
case QCryptographicHash::Blake2s_224:
+ static_assert(224 / 8 <= MaxHashLength);
return 224 / 8;
case QCryptographicHash::RealSha3_256:
case QCryptographicHash::Keccak_256:
case QCryptographicHash::Blake2b_256:
case QCryptographicHash::Blake2s_256:
+ static_assert(256 / 8 <= MaxHashLength);
return 256 / 8;
case QCryptographicHash::RealSha3_384:
case QCryptographicHash::Keccak_384:
case QCryptographicHash::Blake2b_384:
+ static_assert(384 / 8 <= MaxHashLength);
return 384 / 8;
case QCryptographicHash::RealSha3_512:
case QCryptographicHash::Keccak_512:
case QCryptographicHash::Blake2b_512:
+ static_assert(512 / 8 <= MaxHashLength);
return 512 / 8;
#endif
+#undef CASE
}
return 0;
}
@@ -194,7 +200,8 @@ public:
void reset() noexcept;
void addData(QByteArrayView bytes) noexcept;
- QByteArray finalize();
+ void finalize() noexcept;
+ QByteArrayView resultView() const noexcept { return result.toByteArrayView(); }
const QCryptographicHash::Algorithm method;
union {
@@ -219,7 +226,25 @@ public:
};
void sha3Finish(int bitCount, Sha3Variant sha3Variant);
#endif
- QByteArray result;
+ class SmallByteArray {
+ std::array<char, MaxHashLength> m_data;
+ static_assert(MaxHashLength <= std::numeric_limits<std::uint8_t>::max());
+ std::uint8_t m_size;
+ public:
+ char *data() noexcept { return m_data.data(); }
+ const char *data() const noexcept { return m_data.data(); }
+ qsizetype size() const noexcept { return qsizetype{m_size}; }
+ bool isEmpty() const noexcept { return size() == 0; }
+ void clear() noexcept { m_size = 0; }
+ void resize(qsizetype s) {
+ Q_ASSERT(s >= 0);
+ Q_ASSERT(s <= MaxHashLength);
+ m_size = std::uint8_t(s);
+ }
+ QByteArrayView toByteArrayView() const noexcept
+ { return QByteArrayView{data(), size()}; }
+ };
+ SmallByteArray result;
};
#ifndef QT_CRYPTOGRAPHICHASH_ONLY_SHA1
@@ -337,7 +362,7 @@ QCryptographicHash::~QCryptographicHash()
/*!
Resets the object.
*/
-void QCryptographicHash::reset()
+void QCryptographicHash::reset() noexcept
{
d->reset();
}
@@ -532,17 +557,33 @@ bool QCryptographicHash::addData(QIODevice *device)
/*!
Returns the final hash value.
- \sa QByteArray::toHex()
+ \sa resultView(), QByteArray::toHex()
*/
QByteArray QCryptographicHash::result() const
{
- return d->finalize();
+ return resultView().toByteArray();
+}
+
+/*!
+ \since 6.3
+
+ Returns the final hash value.
+
+ Note that the returned view remains valid only as long as the QCryptographicHash object is
+ not modified by other means.
+
+ \sa result(), QByteArrayView::toHex()
+*/
+QByteArrayView QCryptographicHash::resultView() const noexcept
+{
+ d->finalize();
+ return d->resultView();
}
-QByteArray QCryptographicHashPrivate::finalize()
+void QCryptographicHashPrivate::finalize() noexcept
{
if (!result.isEmpty())
- return result;
+ return;
switch (method) {
case QCryptographicHash::Sha1: {
@@ -630,7 +671,6 @@ QByteArray QCryptographicHashPrivate::finalize()
}
#endif
}
- return result;
}
/*!
@@ -643,7 +683,8 @@ QByteArray QCryptographicHash::hash(QByteArrayView data, Algorithm method)
{
QCryptographicHashPrivate hash(method);
hash.addData(data);
- return hash.finalize();
+ hash.finalize();
+ return hash.resultView().toByteArray();
}
/*!
diff --git a/src/corelib/tools/qcryptographichash.h b/src/corelib/tools/qcryptographichash.h
index aecf8995d5..b3ab9c6126 100644
--- a/src/corelib/tools/qcryptographichash.h
+++ b/src/corelib/tools/qcryptographichash.h
@@ -102,7 +102,7 @@ public:
explicit QCryptographicHash(Algorithm method);
~QCryptographicHash();
- void reset();
+ void reset() noexcept;
#if QT_DEPRECATED_SINCE(6, 4)
QT_DEPRECATED_VERSION_X_6_4("Use the QByteArrayView overload instead")
@@ -115,6 +115,7 @@ public:
bool addData(QIODevice *device);
QByteArray result() const;
+ QByteArrayView resultView() const noexcept;
#ifdef QT_BUILD_FUNCTIONS_REMOVED_IN_6_3
static QByteArray hash(const QByteArray &data, Algorithm method);
diff --git a/src/corelib/tools/qmessageauthenticationcode.cpp b/src/corelib/tools/qmessageauthenticationcode.cpp
index 9580b024c2..767a7a14d4 100644
--- a/src/corelib/tools/qmessageauthenticationcode.cpp
+++ b/src/corelib/tools/qmessageauthenticationcode.cpp
@@ -251,7 +251,7 @@ QByteArray QMessageAuthenticationCode::result() const
const int blockSize = qt_hash_block_size(d->method);
- QByteArray hashedMessage = d->messageHash.result();
+ QByteArrayView hashedMessage = d->messageHash.resultView();
QVarLengthArray<char> oKeyPad(blockSize);
const char * const keyData = d->key.constData();
diff --git a/src/network/kernel/qauthenticator.cpp b/src/network/kernel/qauthenticator.cpp
index 04698ddbfa..6cfa1ff2ef 100644
--- a/src/network/kernel/qauthenticator.cpp
+++ b/src/network/kernel/qauthenticator.cpp
@@ -1239,7 +1239,6 @@ QByteArray qEncodeHmacMd5(QByteArray &key, const QByteArray &message)
Q_ASSERT_X(!(key.isEmpty()),"qEncodeHmacMd5", "Empty key check");
QCryptographicHash hash(QCryptographicHash::Md5);
- QByteArray hMsg;
QByteArray iKeyPad(blockSize, 0x36);
QByteArray oKeyPad(blockSize, 0x5c);
@@ -1272,7 +1271,7 @@ QByteArray qEncodeHmacMd5(QByteArray &key, const QByteArray &message)
hash.reset();
hash.addData(iKeyPad);
- hMsg = hash.result();
+ QByteArrayView hMsg = hash.resultView();
//Digest gen after pass-1: H((K0 xor ipad)||text)
QByteArray hmacDigest;
diff --git a/src/plugins/tls/shared/qtlskey_generic.cpp b/src/plugins/tls/shared/qtlskey_generic.cpp
index b9eaf3c1f6..495ccec681 100644
--- a/src/plugins/tls/shared/qtlskey_generic.cpp
+++ b/src/plugins/tls/shared/qtlskey_generic.cpp
@@ -424,9 +424,9 @@ QByteArray deriveAesKey(QSslKeyPrivate::Cipher cipher, const QByteArray &passPhr
hash.addData(data);
if (cipher == Cipher::Aes192Cbc)
- return key.append(hash.result().constData(), 8);
+ return key.append(hash.resultView().first(8));
- return key.append(hash.result());
+ return key.append(hash.resultView());
}
QByteArray deriveKey(QSslKeyPrivate::Cipher cipher, const QByteArray &passPhrase,
diff --git a/tests/auto/corelib/tools/qcryptographichash/tst_qcryptographichash.cpp b/tests/auto/corelib/tools/qcryptographichash/tst_qcryptographichash.cpp
index 7fb9b69a03..6b61349d01 100644
--- a/tests/auto/corelib/tools/qcryptographichash/tst_qcryptographichash.cpp
+++ b/tests/auto/corelib/tools/qcryptographichash/tst_qcryptographichash.cpp
@@ -78,15 +78,17 @@ void tst_QCryptographicHash::repeated_result()
hash.addData(first);
QFETCH(QByteArray, hash_first);
- QByteArray result = hash.result();
+ QByteArrayView result = hash.resultView();
QCOMPARE(result, hash_first);
+ QCOMPARE(result, hash.resultView());
QCOMPARE(result, hash.result());
hash.reset();
hash.addData(first);
- result = hash.result();
+ result = hash.resultView();
QCOMPARE(result, hash_first);
QCOMPARE(result, hash.result());
+ QCOMPARE(result, hash.resultView());
}
void tst_QCryptographicHash::intermediary_result_data()
@@ -179,16 +181,14 @@ void tst_QCryptographicHash::intermediary_result()
hash.addData(first);
QFETCH(QByteArray, hash_first);
- QByteArray result = hash.result();
- QCOMPARE(result, hash_first);
+ QCOMPARE(hash.resultView(), hash_first);
// don't reset
QFETCH(QByteArray, second);
QFETCH(QByteArray, hash_firstsecond);
hash.addData(second);
- result = hash.result();
- QCOMPARE(result, hash_firstsecond);
+ QCOMPARE(hash.resultView(), hash_firstsecond);
hash.reset();
}