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;