From 06a2101e952fcf3baa4cdbcfda5c32cbb316bb34 Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Thu, 23 Feb 2023 16:38:27 +0100 Subject: [PATCH] QMessageAuthenticationCode: make finalizeUnchecked() properly noexcept MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replace the QVarLengthArray with HashBlock, an instantiation of QSmallByteArray. Unlike QVLA, which may allocate memory when capacity() exceeds Prealloc (not the case here, but could become an issue with future hash algorithms, we're at 144 now, up from the traditional 64), QSmallByteArray never throws, and the few Q_ASSERT()s it contains don't matter, because we use the class' functions in-contract here. Requires to add an indexing operator to QSmallByteArray. Pick-to: 6.5 Change-Id: Ica3656adc190e0141e065287fadc38e0cebce0f4 Reviewed-by: MÃ¥rten Nordheim Reviewed-by: Thiago Macieira --- src/corelib/tools/qcryptographichash.cpp | 25 ++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/src/corelib/tools/qcryptographichash.cpp b/src/corelib/tools/qcryptographichash.cpp index 012621fe00f..3ed2ebcab46 100644 --- a/src/corelib/tools/qcryptographichash.cpp +++ b/src/corelib/tools/qcryptographichash.cpp @@ -131,6 +131,11 @@ public: // all SMFs are ok! quint8 *data() noexcept { return m_data.data(); } qsizetype size() const noexcept { return qsizetype{m_size}; } + quint8 &operator[](qsizetype n) + { + Q_ASSERT(n < size()); + return data()[n]; + } bool isEmpty() const noexcept { return size() == 0; } void clear() noexcept { m_size = 0; } void resizeForOverwrite(qsizetype s) @@ -1003,6 +1008,17 @@ static constexpr int qt_hash_block_size(QCryptographicHash::Algorithm method) return 0; } +constexpr int maxHashBlockSize() +{ + int result = 0; + using A = QCryptographicHash::Algorithm; + for (int i = 0; i < A::NumAlgorithms ; ++i) + result = std::max(result, qt_hash_block_size(A(i))); + return result; +} + +using HashBlock = QSmallByteArray; + class QMessageAuthenticationCodePrivate { public: @@ -1022,7 +1038,7 @@ public: // when not called from the static hash() function, this function needs to be // called with finalizeMutex held: - void finalizeUnchecked(); + void finalizeUnchecked() noexcept; // END functions that need to be called with finalizeMutex held }; @@ -1201,21 +1217,22 @@ void QMessageAuthenticationCodePrivate::finalize() finalizeUnchecked(); } -void QMessageAuthenticationCodePrivate::finalizeUnchecked() +void QMessageAuthenticationCodePrivate::finalizeUnchecked() noexcept { const int blockSize = qt_hash_block_size(method); messageHash.finalizeUnchecked(); const HashResult hashedMessage = messageHash.result; - QVarLengthArray oKeyPad(blockSize); + HashBlock oKeyPad; + oKeyPad.resizeForOverwrite(blockSize); const char * const keyData = key.constData(); for (int i = 0; i < blockSize; ++i) oKeyPad[i] = keyData[i] ^ 0x5c; messageHash.reset(); - messageHash.addData(oKeyPad); + messageHash.addData(oKeyPad.toByteArrayView()); messageHash.addData(hashedMessage.toByteArrayView()); messageHash.finalizeUnchecked();