From 2b6a77cd1509322c5a6f71d5fdbdae68b806080d Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Tue, 21 May 2024 14:54:59 +0200 Subject: [PATCH] QMessageAuthenticationCode: add hashInto() overloads MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Same change as previously done for QCryptographicHash; same rationale applies. [ChangeLog][QtCore][QMessageAuthenticationCode] Added hashInto() methods, see QCryptographicHash for more information. Fixes: QTBUG-125431 Change-Id: I88a15479b020b39ff0669a9615793886289c83f7 Reviewed-by: MÃ¥rten Nordheim --- src/corelib/tools/qcryptographichash.cpp | 41 ++++++++++++++++++- .../tools/qmessageauthenticationcode.h | 24 +++++++++++ 2 files changed, 63 insertions(+), 2 deletions(-) diff --git a/src/corelib/tools/qcryptographichash.cpp b/src/corelib/tools/qcryptographichash.cpp index f64f11ee44..d0ed17eba2 100644 --- a/src/corelib/tools/qcryptographichash.cpp +++ b/src/corelib/tools/qcryptographichash.cpp @@ -1671,15 +1671,52 @@ void QMessageAuthenticationCodePrivate::finalizeUnchecked() noexcept the key \a key and the method \a method. \include qcryptographichash.cpp {qba-to-qbav-6.6} + + \sa hashInto() */ QByteArray QMessageAuthenticationCode::hash(QByteArrayView message, QByteArrayView key, QCryptographicHash::Algorithm method) +{ + QByteArray ba(hashLengthInternal(method), Qt::Uninitialized); + [[maybe_unused]] const auto r = hashInto(ba, message, key, method); + Q_ASSERT(r.size() == ba.size()); + return ba; +} + +/*! + \since 6.8 + \fn QMessageAuthenticationCode::hashInto(QSpan buffer, QSpan messageParts, QByteArrayView key, QCryptographicHash::Algorithm method); + \fn QMessageAuthenticationCode::hashInto(QSpan buffer, QSpan messageParts, QByteArrayView key, QCryptographicHash::Algorithm method); + \fn QMessageAuthenticationCode::hashInto(QSpan buffer, QSpan messageParts, QByteArrayView key, QCryptographicHash::Algorithm method); + \fn QMessageAuthenticationCode::hashInto(QSpan buffer, QByteArrayView message, QByteArrayView key, QCryptographicHash::Algorithm method); + \fn QMessageAuthenticationCode::hashInto(QSpan buffer, QByteArrayView message, QByteArrayView key, QCryptographicHash::Algorithm method); + \fn QMessageAuthenticationCode::hashInto(QSpan buffer, QByteArrayView message, QByteArrayView key, QCryptographicHash::Algorithm method); + + Returns the authentication code for the message (\a message or, for the + QSpan overloads, the concatenation of \a messageParts) using the key \a key + and the method \a method. + + The return value will be a sub-span of \a buffer, unless \a buffer is of + insufficient size, in which case a null QByteArrayView is returned. + + \sa hash() +*/ +QByteArrayView QMessageAuthenticationCode::hashInto(QSpan buffer, + QSpan messageParts, + QByteArrayView key, + QCryptographicHash::Algorithm method) noexcept { QMessageAuthenticationCodePrivate mac(method); mac.setKey(key); - mac.messageHash.addData(message); + for (QByteArrayView part : messageParts) + mac.messageHash.addData(part); mac.finalizeUnchecked(); - return mac.messageHash.resultView().toByteArray(); + auto result = mac.messageHash.resultView(); + if (buffer.size() < result.size()) + return {}; // buffer too small + // ### optimize: have the method directly write into `buffer` + memcpy(buffer.data(), result.data(), result.size()); + return buffer.first(result.size()); } QT_END_NAMESPACE diff --git a/src/corelib/tools/qmessageauthenticationcode.h b/src/corelib/tools/qmessageauthenticationcode.h index 4e88138763..7c5edfa7bf 100644 --- a/src/corelib/tools/qmessageauthenticationcode.h +++ b/src/corelib/tools/qmessageauthenticationcode.h @@ -55,6 +55,30 @@ public: static QByteArray hash(QByteArrayView message, QByteArrayView key, QCryptographicHash::Algorithm method); + static QByteArrayView + hashInto(QSpan buffer, QByteArrayView message, QByteArrayView key, + QCryptographicHash::Algorithm method) noexcept + { return hashInto(as_writable_bytes(buffer), {&message, 1}, key, method); } + static QByteArrayView + hashInto(QSpan buffer, QByteArrayView message, QByteArrayView key, + QCryptographicHash::Algorithm method) noexcept + { return hashInto(as_writable_bytes(buffer), {&message, 1}, key, method); } + static QByteArrayView + hashInto(QSpan buffer, QByteArrayView message, + QByteArrayView key, QCryptographicHash::Algorithm method) noexcept + { return hashInto(buffer, {&message, 1}, key, method); } + static QByteArrayView + hashInto(QSpan buffer, QSpan messageParts, + QByteArrayView key, QCryptographicHash::Algorithm method) noexcept + { return hashInto(as_writable_bytes(buffer), messageParts, key, method); } + static QByteArrayView + hashInto(QSpan buffer, QSpan messageParts, + QByteArrayView key, QCryptographicHash::Algorithm method) noexcept + { return hashInto(as_writable_bytes(buffer), messageParts, key, method); } + static QByteArrayView + hashInto(QSpan buffer, QSpan message, + QByteArrayView key, QCryptographicHash::Algorithm method) noexcept; + private: Q_DISABLE_COPY(QMessageAuthenticationCode) QMessageAuthenticationCodePrivate *d;